@alexsemen94
начинающий прогаммист

Как в JavaFX создать поток который будет добавлять Label, пока не нажать кнопку Stop?

Как в JavaFX создать поток который будет добавлять Label, пока не нажать кнопку Stop?

если создавать что-то типо такого, то вылетает ошибка - Not on FX application thread; currentThread = Thread-4
Thread addLabel = new Thread(new Runnable() {
            @Override
            public void run() {
                while(start) {
                    vBox.getChildren().addAll(new Label("new label"));
                }
            }
        });
  • Вопрос задан
  • 2734 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
JavaFX, как и многие другие gui-библиотеки, однопоточна. При создании окна создаётся Event Dispatch Thread, внутри которого будет работать цикл событий и обработчики событий. Вы не должны пытаться из главного потока или любого другого потока взаимодействовать с элементами графического интерфейса - это приведёт к сбою. Вы не должны внутри обработчиков событий запускать потоки - это приведёт к сбою. Если вам надо из другого потока изменить, например, текст метки, то придётся создать задание для EDT:
Platform.runLater((() -> someLabel.setText("Hello"));

Если вам нужно внутри обработчика нажатия на кнопку запустить на выполнение длительную задачу, придётся использовать Task и Service:
public class Example extends Application {
    ...

    btn.setOnAction(act -> {
        Service<Void> service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        // Долгий код
                        return null;
                    }
                };
            }
        };
        service.start();
    });
}

Примечание
На самом деле поток обработки событий в JavaFX называется JavaFX Application Thread, но это непринципиально.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@kalininmr
тут лучше применить обратную стратегию.
создаем поток, который долго думает, а из него как либо информируем поток гуи, дабы он уже создавал лэйбл.
Ответ написан
Комментировать
Я лично, чтобы изменять UI с потока JavaFx использую либо
AnimationTimer или Platform.runLater
но в основном AnimationTimer
boolean update=false;
        AnimationTimer animationTimer=new AnimationTimer() {
            @Override
            public void handle(long now) {
                // от здесь уже процесс от JavaFx,  можешь спокойно обновлять UI
                if(update){
                    update=false;
                    // обычно у меня так выглядет
                    // TODO обновление UI
                }
            }
        };
        animationTimer.start();


runLater почему-то я пока нигде ни использовал, но пробывал
Platform.runLater(new Runnable() {
            @Override
            public void run() {
                //  здесь уже поток от JavaFx
            }
        });


есть еще пару способов связанный с чем-то типа Task, но его не опробовал, из за усложненности
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽