我正在使用一种应用程序功能来显示TextArea
中的进度状态。我正在使用观察者模式来实现这一点。但是,当我尝试将状态信息附加到TextArea
时,窗口冻结。如何解决这个问题?
冻结窗口如下:doSomething()
完成后。冻结窗口恢复正常。像这样:
这是我的代码
start(Stage stage)
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("view/progressStatus.fxml"));
Parent root = loader.load();
statusStage = new Stage();
statusScene = new Scene(root);
statusStage.setScene(statusScene);
progressStatusController = loader.getController();
statusStage.show();
MyFiles myFiles = new MyFiles();
myFiles.addObserver(progressStatusController);
newMyFiles.doSomething();
public class ProgressStatusController implements Initializable, Observer {
@FXML private ProgressBar progressBar;
@FXML private TextArea textArea;
private String[] message;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@Override
public void update(Observable o, Object arg) {
System.out.println(arg);
textArea.textProperty().set(textArea.getText().concat("\n").concat((String)arg));
textArea.positionCaret(textArea.getText().length());
}
}
最佳答案
doSomething
是一项长期运行的任务,因此不应在JavaFX应用程序线程上运行。但是,start
方法在此线程上运行。
您需要在其他线程上运行doSomething
以避免阻塞应用程序线程。对UI的更新应在应用程序线程上完成;因此,您应该使用Platform.runLater
执行更新:
...
MyFiles myFiles = new MyFiles();
myFiles.addObserver(progressStatusController);
new Thread(newMyFiles::doSomething).start();
@Override
public void update(Observable o, Object arg) {
System.out.println(arg);
Platform.runLater(() -> {
textArea.setText(textArea.getText() + "\n" + arg);
textArea.positionCaret(textArea.getText().length());
});
}