[英]JavaFX : Not on FX application thread error occurs
我想在某些任务正在工作时弹出progressindecator。 为了做到这一点,我对程序进行了如下编码。
public void handleCheckButtonOnAction(Button button, DBConnect conn) {
ProgressForm pForm = new ProgressForm();
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
checkTargetDatabaseInfo();
updateProgress(-1, -1);
return null;
}
};
pForm.activateProgressBar(task);
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
});
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
}
在checkTargetDatabaseInfo方法内部有一个更改标签的功能。
和这样的错误。
Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:145)
at managerworld.controller.SetEnvironmentViewerController.checkTargetDatabaseInfo(SetEnvironmentViewerController.java:142)
at managerworld.controller.SetEnvironmentViewerController.access$600(SetEnvironmentViewerController.java:42)
at managerworld.controller.SetEnvironmentViewerController$1.call(SetEnvironmentViewerController.java:109)
at managerworld.controller.SetEnvironmentViewerController$1.call(SetEnvironmentViewerController.java:98)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)
安德烈亚斯,我终于找到了答案,无论如何,我非常感激,您的评论对我很有帮助。
我在Platform.runLater方法中插入了一些将UI方法更新的代码,并且效果很好。 这是我的代码。
private void checkDBVersion () {
ProgressForm pForm = new ProgressForm();
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
SimpleStringProperty version = new SimpleStringProperty();
Connection targetDBconn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
targetDBconn = globalTargetConn.connect();
Platform.runLater(new Runnable(){@Override public void run() {logWriter.writeLogs(logTextArea, LogWriter.INFO, "Checking this database version...");}});
pstmt = new LoggableStatement(targetDBconn, SqlList.checkTargetDBVersionSQL);
String SQL = ((LoggableStatement) pstmt).getQueryString();
Platform.runLater(new Runnable(){@Override public void run() {logWriter.writeLogs(logTextArea, LogWriter.INFO, "See the query below...");}});
Platform.runLater(new Runnable(){@Override public void run() {logWriter.writeLogs(logTextArea, LogWriter.INFO, SQL);}});
rs = pstmt.executeQuery();
while (rs.next()) {
version.set(rs.getString(1));
targetDatabaseInfo.setVersion(version);
}
Platform.runLater(new Runnable(){@Override public void run() {logWriter.writeLogs(logTextArea, LogWriter.INFO, "Your database version is " + version.getValue());}});
} catch (SQLException ex) {Platform.runLater(new Runnable(){@Override public void run() {logWriter.writeLogs(logTextArea, LogWriter.ERROR, ex.getMessage());}});
} finally {
if (rs != null ) try {rs.close();} catch(SQLException ex) {}
if (pstmt != null ) try {pstmt.close();} catch(SQLException ex) {}
if (targetDBconn != null ) try {targetDBconn.close();} catch(SQLException ex) {}
}
_DB_VERSION = version;
updateProgress(-1, -1);
return null;
}
};
pForm.activateProgressBar(task);
task.setOnSucceeded(event -> {
pForm.getDialogStage().close();
});
pForm.getDialogStage().show();
Thread thread = new Thread(task);
thread.start();
}
完成此操作后,我很好奇是否是后台作业。 是进度条后台作业吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.