Lan*_*hhh 3 java multithreading javafx
我正在学习 JavaFX 并且我制作了一个演示应用程序,该应用程序具有 Label 检测值更改并更改其显示。我试图将 Label.textProperty 绑定到该值,但仍然不起作用。这是我的代码:
public class MainApp extends Application {
public static void main(String[] args) {
launch(args);
}
private Temp aTemp = new Temp();
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Sample.fxml"));
BorderPane root = (BorderPane)loader.load();
SampleController sampleController = loader.getController();
Scene scene = new Scene(root,600,600);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
sampleController.setModel(aTemp);
} catch(Exception e) {
e.printStackTrace();
}
}}
Run Code Online (Sandbox Code Playgroud)
这是模型
public class Temp {
private StringProperty temp = new SimpleStringProperty("a");
private final ExecutorService service = Executors.newCachedThreadPool();
public Temp() {
task.startConnection();
service.submit(new Task<Integer>() {
@Override
public Integer call() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {
e.printStackTrace();
}
setTemp(getTemp() + "b");
System.out.println(getTemp());
}
}
});
}
public StringProperty getProperty() {
return this.temp;
}
public String getTemp() {
return this.temp.get();
}
public void setTemp(String value) {
this.temp.set(value);
}
Run Code Online (Sandbox Code Playgroud)
然后控制器
public class SampleController implements Initializable {
private Temp aTemp;
@FXML private Label tempLabel;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
public void setModel(Temp aTemp) {
this.aTemp = aTemp;
Platform.runLater(new Runnable() {
@Override
public void run() {
tempLabel.textProperty().bind(aTemp.getProperty());
}
});
}}
Run Code Online (Sandbox Code Playgroud)
我得到的是 Label 更改为“a”但之后不会更改,并且此异常:
Exception in thread "pool-2-thread-1"
java.lang.IllegalStateException: Not on FX application thread; currentThread = pool-2-thread-1
Run Code Online (Sandbox Code Playgroud)
充实我的评论:如果你想让模型完全不知道 UI,那么不要将它直接绑定到控件的属性。相反,在 UI 端有一些对模型属性的侦听器,可以更改 fx 线程上的控件属性。
代码片段(未经测试,只是复制和调整 - 所以甚至可能无法编译;):
public void setModel(Temp aTemp) {
this.aTemp = aTemp;
aTemp.tempProperty().addListener(this::updateLabelText)
}}
private void updateLabelText() {
Platform.runLater(() -> label.setText(aTemp.getTemp()));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
706 次 |
| 最近记录: |