[英]How to call JavaFX controller from non JavaFX thread and wait for the GUI changes to finish (finish playing video)?
I have 2 classes: Controller
( JavaFX
controller) and MachineController
(not JavaFX
thread). 我有2类:
Controller
( JavaFX
控制器)和MachineController
(不是JavaFX
线程)。 Sometimes MachineController
sent message to Controller
using method setMessage
. 有时
MachineController
使用setMessage
方法将消息发送到Controller
。
Method setMessage(String str)
should update GUI by adding String
to the List
and on the Label
, also if it is necessary, I shoul play the video or show Images, but i must wait for end of playing video or end of showing Image (it shows some time (for example, 3-4 seconds)). setMessage(String str)
应通过将String
添加到List
和Label
setMessage(String str)
更新GUI,如果有必要,我也应该播放视频或显示图像,但是我必须等待视频播放结束或图像显示结束(它显示一些时间(例如3-4秒)。
I have used Task
and Platform.runLater()
. 我已经使用
Task
和Platform.runLater()
。 But if i use Task
Images are shown only sometimes, and video wasn't played at all. 但是,如果我使用“
Task
图像”,则仅在某些时候显示,而根本没有播放视频。 If i use Platform.runLater
i couldn't wait to end of playing video or shoeing image, because it start in the futere. 如果我使用
Platform.runLater
我将迫不及待想要播放视频或启动图像,因为它始于futere。
Controller 调节器
public void setMessage(final String str) {
Task<Void> task = new Task<>() {
boolean test = true;
@Override
protected Void call() throws Exception {
while (test) {
currentCommandLabel.setText(str);
commands.add(str);
Executable show = analyze.getExec(str);
show.exec(pane);
Thread.sleep(1000);
}
return null;
}
};
Thread thread = new Thread(task);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Executable 可执行文件
interface Executable {
void exec(GridPane pane);
}
Analize Analize
Executable getExec(String string) {
return panel -> {
cleanZeroCell(pane1);
File fileImage = new File("<path to image file>");
Image image = new Image(fileImage.toURI().toString());
imageView.setImage(image);
panel.add(imageView, 0, 0);
};
}
Also I have tried to used setMessage
like this: 我也尝试过使用
setMessage
这样的:
public void setMessage(final String str) {
Platform.runLater(() -> {
currentCommandLabel.setText(str);
commands.add(str);
});
Executable show = analyze.getExec(str);
Platform.runLater(() -> show.exec(pane));
}
You can use a CountDownLatch
to wait for the JavaFX application thread on a non-application thread. 您可以使用
CountDownLatch
在非应用程序线程上等待JavaFX应用程序线程。 The following example uses a animation instead of a video or "image showing", but you could easily use the MediaPlayer.onEndOfMedia
event instead of Animation.onFinished
event: 下面的示例使用动画而不是视频或“图像显示”,但是您可以轻松地使用
MediaPlayer.onEndOfMedia
事件而不是Animation.onFinished
事件:
private void startAnimation(Button button, CountDownLatch latch) {
TranslateTransition animation = new TranslateTransition(Duration.seconds(2), button);
animation.setByX(100);
animation.setOnFinished(evt -> latch.countDown());
animation.play();
}
@Override
public void start(Stage primaryStage) {
Button btn = new Button("Animate");
btn.setOnAction((ActionEvent event) -> {
new Thread(() -> {
try {
// simulates some work prior to modifying the ui
Thread.sleep(2000);
} catch (InterruptedException ex) {
}
CountDownLatch latch = new CountDownLatch(1);
// start animation on application thread
Platform.runLater(() -> startAnimation(btn, latch));
try {
// wait for application thread to count down the latch
latch.await();
System.out.println("Done");
} catch (InterruptedException ex) {
ex.printStackTrace(System.err);
}
}).start();
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.