问题描述
我正在尝试创建一个设置GUI的环境,当用户通过侦听器修改其组件时,另一个线程每隔X秒向其添加一个新元素。 (这是一个游戏,是的)
I am trying to create an environment, in which a GUI is set up, and while the user is modifying its components through listeners, another thread is adding new elements to it every X seconds. (it is a game, yes)
我希望游戏在一个类中,而元素加法器在另一个类中 - 但当然Java抱怨我无法从另一个线程修改JavaFX GUI。
I want the game to be in one class, and the "element adder" thread in another - but of course Java complains that I cannot modify JavaFX GUI from another thread.
我见过使用Platform.runLater()的解决方案,但据我所知,所有这些解决方案都使用匿名内部类。我真的希望我的加法器在另一个(命名)类中。
I've seen solutions using Platform.runLater() but as far as I see, all these solutions use anonymous inner classes. And I really want my adder to be in another (named) class.
任何提示都会非常感激,这是代码的最小版本,可以重现问题:
Any hints would be really appreciated, here's a minimal version of the code, that reproduces the problem:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class DifferentThreadJavaFXMinimal extends Application {
private Thread t;
private GridPane gp;
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
gp = new GridPane();
Scene gameScene = new Scene(gp, 600,500);
primaryStage.setScene(gameScene);
t = new Thread(new Thread2(instance()));
primaryStage.show();
t.start();
}
void addElement(int i) {
Button actualButton = new Button("TEST");
gp.add(actualButton,i,i);
}
public DifferentThreadJavaFXMinimal instance(){
return this;
}
}
class Thread2 implements Runnable {
private DifferentThreadJavaFXMinimal d;
Thread2(DifferentThreadJavaFXMinimal dt){
d=dt;
}
@Override
public void run() {
for (int i=0;i<4;i++) {
d.addElement(i);
}
}
}
推荐答案
您仍然可以使用独立类。
You can still use your standalone class.
规则是必须在FX应用程序线程上更改UI。您可以通过包装来自其他线程的调用来实现这一点,这些线程会更改您传递给 Platform.runLater(...)的
。 Runnable
中的UI
The rule is that changes to the UI must happen on the FX Application Thread. You can cause that to happen by wrapping calls from other threads that change the UI in Runnable
s that you pass to Platform.runLater(...)
.
在您的示例代码中, d.addElement(i)
更改了UI ,所以你会这样做:
In your example code, d.addElement(i)
changes the UI, so you would do:
class Thread2 implements Runnable {
private DifferentThreadJavaFXMinimal d;
Thread2(DifferentThreadJavaFXMinimal dt){
d=dt;
}
@Override
public void run() {
for (int i=0;i<4;i++) {
final int value = i ;
Platform.runLater(() -> d.addElement(value));
// presumably in real life some kind of blocking code here....
}
System.out.println("Hahó");
}
}
这篇关于从不同类中的不同线程修改JavaFX gui的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!