@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"));
                }
            }
        });
  • Вопрос задан
  • 2733 просмотра
Решения вопроса 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, но его не опробовал, из за усложненности
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы