JavaFX:Not on FX应用程序线程出错



我想在执行某些任务时弹出进度指示器。为了做到这一点,我对我的程序进行了如下编码。。

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)

Andreas,我终于自己找到了答案,无论如何,我非常感谢,你的评论对我很有帮助。

我在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();
    }

完成后,我只是好奇是否是背景工作。进度条是后台工作吗??

最新更新