2015-12-08 75 views
1

我想在某些任務正在工作時彈出progressindecator。爲了做到這一點,我編寫我的程序,如以下..JavaFX:不在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) 
+1

您不能在任務線程中調用UI方法('Labeled.setText()')。取而代之的是,存儲'checkTargetDatabaseInfo'調用的結果,並將用戶界面更新到像'setOnSucceed'這樣的任務處理程序中。 https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html:'因爲該任務是爲與JavaFX GUI應用程序一起使用而設計的,所以它確保對其公共屬性的每個更改以及狀態,錯誤和事件處理程序的更改通知,都發生在主要JavaFX應用程序線程上。「 –

+1

Andreas您的評論是一個答案,請使其成爲可能。 – jewelsea

+0

@Andreas,但其他UI方法如圓圈怎麼樣?我在checkTargetDatabaseInfo方法中改變了一個圓的顏色。 – James

回答

1

安德烈亞斯,我終於找到自己的答案,反正它是如此感恩,您的評論會爲我很大的幫助。

我插入了一些更新UI方法到Platform.runLater方法的代碼,它工作正常。這是我的代碼..

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

完成這個後,我只是好奇,是否是後臺工作,而不是。進度條背景工作嗎?

相關問題