Я пытаюсь обеспечить обратную связь в приложении JavaFX 8, когда пользователь выбирает пункт меню, который запускает процесс блокировки в другом потоке. В моем реальном приложении это загрузка файла, но я создал тестовый пример с использованием минимального кода в качестве примера:Почему поток блокирует мою тему JavaFX UI?
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.ToolBar;
import javafx.scene.control.MenuItem;
import javafx.stage.Stage;
public class BlockingThreadTestCase extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
MenuItem menuItem = new MenuItem("Start");
MenuButton menuButton = new MenuButton();
menuButton.setText("Async Process");
menuButton.getItems().addAll(menuItem);
menuItem.setOnAction(event -> {
menuButton.setText("Running...");
Platform.runLater(() -> {
try {
// Simulate a blocking process
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
menuButton.setText(menuButton.getText() + "Done!");
});
});
final ToolBar toolbar = new ToolBar(menuButton);
final Scene scene = new Scene(toolbar);
primaryStage.setScene(scene);
primaryStage.setWidth(150);
primaryStage.show();
}
}
Вот как это должно работать: При выборе пункта меню «Пуск», главном текст меню должен немедленно измениться на «Запуск ...», а затем он должен добавить «Готово!». после 5-секундного сна, который имитирует загрузку моего файла.
Что на самом деле происходит, как текст обновления стрельбы после блокирующий процесс делается, несмотря на то, я использую Platform.runLater()
. Что я делаю не так?
'Platform.runLater' будет выполнять блок« Runnable »в разделе« Dispatching Thread », что означает, что он заблокирует ваш пользовательский интерфейс. Это не то, как вы хотите отсрочить обратные вызовы, я не знаком с JavaFX, но вы хотите, чтобы какой-то «таймер» мог быть выполнен (с задержкой в 5 секунд) и который при запуске может обновить состояние вас меню в контексте EDT – MadProgrammer
Используйте [Задача] (https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm), запущенную в новом потоке, который вы создаете. – jewelsea
Я попытался создать свой собственный поток, но затем я получаю сообщение об ошибке при попытке обновить текст меню, потому что изменения интерфейса JavaFX могут быть сделаны только из основного потока пользовательского интерфейса. –