简体   繁体   中英

JavaFX : Not on FX application thread error occurs

I want to pop up the progressindecator while some tasks are working. In order to do this, I coded my program like the followings..

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

There is a function which to change a label inside checkTargetDatabaseInfo method.

and the error like this..

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, I finally find the answer myself, anyway it's so thankful and your comment would very helpful for me.

I inserted some code which update UI method into Platform.runLater method and it worked fine. Here's my code..

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

After this is done, I'm just curious whether is the background job and not. Is progress bar background job??

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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