繁体   English   中英

JavaFX:不在FX应用程序上发生线程错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM