JavaFX 8 图形线程管道
Posted
技术标签:
【中文标题】JavaFX 8 图形线程管道【英文标题】:JavaFX 8 graphic thread pipeline 【发布时间】:2018-06-03 04:01:22 【问题描述】:我正在尝试添加在加载某些 javafx 图形时显示的加载对话框。问题是javafx图形的加载阻塞了加载对话框的刷新。
这是我的代码:
Stage dialogStage;
ProgressBar pb = new ProgressBar();
ProgressIndicator pin = new ProgressIndicator();
dialogStage = new Stage();
dialogStage.initStyle(StageStyle.UTILITY);
dialogStage.setResizable(false);
dialogStage.initModality(Modality.APPLICATION_MODAL);
// PROGRESS BAR
final Label label = new Label();
label.setText("alerto");
pb.setProgress(-1F);
pin.setProgress(-1F);
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(pb, pin);
Scene scene = new Scene(hb);
dialogStage.setScene(scene);
final Task<Void> task = new Task<Void>()
@Override
protected Void call() throws Exception
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "START CALL" + ANSI_RESET);
for (int i = 0; i < 1; i++)
System.out.println(ANSI_CYAN + "\tWAIT " + (i + 1) + "s;" + ANSI_RESET);
try
Thread.sleep(500);
catch (InterruptedException ex)
Logger.getLogger(FXMLDesktopController.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ANSI_CYAN + "\tWAITED " + (i + 1) + "s;" + ANSI_RESET);
Platform.runLater(() ->
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "FIRE APP" + ANSI_RESET);
startGraphic(anchorDesktop);
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "APP FIRED" + ANSI_RESET);
);
for (int i = 0; i < 0; i++)
System.out.println(ANSI_CYAN + "\tWAIT " + (i + 1) + "s;" + ANSI_RESET);
try
Thread.sleep(1000);
catch (InterruptedException ex)
Logger.getLogger(FXMLDesktopController.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ANSI_CYAN + "\tWAITED " + (i + 1) + "s;" + ANSI_RESET);
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "END CALL" + ANSI_RESET);
return null;
;
pb.progressProperty().bind(task.progressProperty());
pin.progressProperty().bind(task.progressProperty());
dialogStage.show();
task.setOnSucceeded(event ->
dialogStage.close();
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "CLOSE" + ANSI_RESET);
);
Platform.runLater(() ->
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "START SHOW" + ANSI_RESET);
);
System.out.println(ANSI_CYAN + ANSI_RED_BACKGROUND + "NEW THEAD" + ANSI_RESET);
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
当startGraphic(anchorDesktop)
被调用时,会阻止进度条的动画,直到所有图形加载完毕。
JavaFX 图形有多线程管道吗?
【问题讨论】:
您在 FX 应用程序线程上明确运行startGraphic
。该方法在做什么?如果它没有改变实际显示的任何内容,则可以在后台线程中运行。
【参考方案1】:
JavaFX 图形有多线程管道吗?
不,所有与 FX UI 相关的事情(有一些记录在案的例外情况)都必须在平台线程上完成。
目前您在平台线程上直接调用startGraphic()
,因此无论该方法在做什么,它都必须在平台线程上发生任何其他事情之前完成执行(包括更新您的加载对话框。)
这可能有点痛苦,但在 UI 工具包中很常见。绕过它的正常方法(假设startGraphic()
进行了一堆 UI 初始化)将启动方法 off UI 线程,然后将各个 UI 操作包装在 Platform.runLater()
而不是一气呵成。在平台线程上拥有大量小型可运行程序将允许它在其间安排对 UI 的更新,包括对加载轮的更新。
【讨论】:
以上是关于JavaFX 8 图形线程管道的主要内容,如果未能解决你的问题,请参考以下文章
JavaFX 多线程之 ThreadPoolExecutor 线程池