2016-01-29 110 views
0

我在控制器類綁定例外:標籤JavaFX中

public void initialize(URL location, ResourceBundle resources) { 
    //set Properties' values at the beginning 
    setProperties(); 
    //bind string properties to labels 
    word.textProperty().bind(wordString); 
    meaning.textProperty().bind(meaningString); 
    sentence.textProperty().bind(sentenceString); 
    //listener to detect change in index and assign strings accordingly 
    DataHelper.intIndexProperty().addListener(
      (v, oldValue, newValue) -> { 
       wordString.setValue(DataHelper.getListOfWords().get((int) newValue).get("word")); 
       meaningString.setValue(DataHelper.getListOfWords().get((int) newValue).get("meaning")); 
       sentenceString.setValue(DataHelper.getListOfWords().get((int) newValue).get("sentence")); 
       System.out.print("kjbmmj"); 
      } 
    ); 
} 

我有一個名爲TimeChecker實施runanble被實例化,並在我的start方法在我Main類開始上課。在TimeChecker類:​​

public void run() { 
    try{ 
     while (!isDone) { 
      System.out.println("Running!!"); 
      System.out.println(); 
      DataHelper.setCurrentDate(LocalDate.now()); 
      if (!DataHelper.getOldDate().equals(DataHelper.getCurrentDate())) { 
       DataHelper.setIntIndex(DataHelper.getIntIndex()+1); 
       DataHelper.setOldDate(DataHelper.getCurrentDate()); 
       DataHelper.saveData(); 
       System.out.println("Saved!"); 
      } 
      Thread.currentThread().sleep(2000); 
     } 

錯誤:

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4 
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204) 
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:438) 
at javafx.scene.Parent$2.onProposedChange(Parent.java:364) 
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.skin.BehaviorSkinBase$$Lambda$160/1022376785.call(Unknown Source) 
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.access$000(StringPropertyBase.java:49) 
at javafx.beans.property.StringPropertyBase$Listener.invalidated(StringPropertyBase.java:230) 
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137) 
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 sample.Controller.lambda$initialize$0(Controller.java:53) 
at sample.Controller$$Lambda$86/694065084.changed(Unknown Source) 
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.IntegerPropertyBase.fireValueChangedEvent(IntegerPropertyBase.java:106) 
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113) 
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147) 
at sample.DataHelper.setIntIndex(DataHelper.java:123) 
at sample.TimeChecker.run(TimeChecker.java:26) 
at java.lang.Thread.run(Thread.java:745) 

我有這個問題時,intIndexPropertylistener火起來。 我知道這個問題還有其他類似的問題。但我無法正確理解答案;我只對我的代碼打破了java的規則有一個模糊的想法,除了主應用程序線程之外的任何線程都無法在任何情況下更改UI。任何人都可以正確解釋它,並回答如何解決這個問題所需的代碼?

+0

見[Platform.runLater](http://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang .Runnable-)。 – VGR

+0

@VGR你能詳細解釋我應該如何在代碼中實現它嗎?我試圖用它來運行線程,但仍然有相同的錯誤。 – absolutezero

+0

@VGR永不知道我以前的評論。它確實有效,但現在我的UI尚未加載。 – absolutezero

回答

0

將僅影響GUI的行纏繞在Platform.runLater()的內部,這樣您就不會使UI無響應。

喜歡:

public void run() { 
    try{ 
     while (!isDone) { 
      System.out.println("Running!!"); 
      System.out.println(); 
      DataHelper.setCurrentDate(LocalDate.now()); 
      if (!DataHelper.getOldDate().equals(DataHelper.getCurrentDate())) { 
       Platform.runLater(new Runnable(){ 
        @Override 
        public void run() { 
         DataHelper.setIntIndex(DataHelper.getIntIndex()+1); 
        } 
       }); 
       DataHelper.setOldDate(DataHelper.getCurrentDate()); 
       DataHelper.saveData(); 
       System.out.println("Saved!"); 
      }