0

So i have a Controller class which contains the ObservableList of StringProperty. And when i change any StringProperty object from another thread, it works. However if i try to bind this StringProperty object to Label and then change this object from different thread it throws tonns of errors. Controller class :

public class Controller implements Initializable{
protected static ObservableList<StringProperty><StringProperty> downloadingsPosition = nFXCollections.observableArrayList();
protected static ObservableList<StringProperty><StringProperty> downloadingsSize = FXCollections.observableArrayList();
private void saveActionEvent() {
...
 position.textProperty().bind(positionString);
 size.textProperty().bind(sizeString);
}
...
}

Process class:

public class Process implements Runnable {
private FileOutputStream fos;
private int number;
private double totalSize;

public Process(FileOutputStream fos, int number, double totalSize) {
    this.fos = fos;
    this.number = number;
    this.totalSize = totalSize;
}

public void run() {
    double size = 0;

    String totalSizeStr = String.valueOf("of " + Double.toString(totalSize / 1024.0));
    Controller.downloadingsSize.get(number).setValue(totalSizeStr);

    try {
        while (size < totalSize) {
            size = fos.getChannel().size() / (1024.0 * 1024.0);
            Controller.downloadingsPosition.get(number).setValue(Double.toString(size));
            TimeUnit.MILLISECONDS.sleep(500);
            System.out.println(size);
        }
    }
    catch (Exception e) {

    }

}

}

These are errors:

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: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$96/698755630.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.Process.run(Process.java:30)
    at java.lang.Thread.run(Thread.java:745)
RisingSun
  • 1,693
  • 27
  • 45
Rustam Ibragimov
  • 2,571
  • 7
  • 22
  • 33
  • 1
    Check this: http://stackoverflow.com/questions/15746474/javafx-how-to-bind-two-values – Frank Aug 27 '15 at 17:10

1 Answers1

0

You'll want to read this article: https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm

The summarized verison is that JavaFX expects any changes to the UI to happen on the Main Thread from which the application is running. If you need to make changes from another thread, you should be using a message queue to talk to the main thread.

Alternately, as described in the article, you could use one of the constructs provided by JavaFX to make changes across threads.

Xirema
  • 19,889
  • 4
  • 32
  • 68