yunhasnawa
yunhasnawa

Reputation: 965

JavaFX UI freeze after receive event from other thread proccess

I am new to JavaFX. What I want to achieve is just updating text on a JavaFX text area after the controller receives event from another thread. But it sometimes will hang with same exception.

Here is what happened:

Other thread -> Trigger event -> Do proccess at an event handler on JavaFX controller -> Hang with exception.

The exception I always get is kind of something like this:

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:371)
    at java.util.ArrayList.get(ArrayList.java:384)
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:208)
    at com.sun.javafx.scene.control.skin.TextAreaSkin$ContentView.layoutChildren(TextAreaSkin.java:291)
    at javafx.scene.Parent.layout(Parent.java:1018)
    at javafx.scene.Parent.layout(Parent.java:1028)
    at javafx.scene.Scene.layoutDirtyRoots(Scene.java:513)
    at javafx.scene.Scene.doLayoutPass(Scene.java:484)
    at javafx.scene.Scene.access$3900(Scene.java:169)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2199)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:363)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:460)
    at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:329)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)

And my code for calling event hendler on event class is just like this:

private void propertyChanged(String propertyName)
{
    CortexInspectorEvent event = new CortexInspectorEvent(this);

    Iterator i = this.listeners.iterator();

    while (i.hasNext())
    {
        ICortexInspectorEventListener listener = (ICortexInspectorEventListener) i.next();

        try
        {
            listener.onProperpertyChanged(event, propertyName);
        }
        catch(Exception ex)
        {
            System.out.println(ex.getMessage());
        }   
    }
}

Even I placed try-catch, the exception is never caught and the UI still hang.

In my event handler method, even I place empty method, again, the UI will still hang.

@Override
public void onProperpertyChanged(CortexInspectorEvent e, String propertyName) 
{
    CortexInspector inspector = (CortexInspector) e.getSource();

    this.logln(inspector.getLog()); // This line of code is just for appending some String to a text area.
}

I don't know how to ask goo*le for a problem like this, I've tried a bunch of keyword and still not get the proper answer, so I ask here. Please help. Thank you.

Upvotes: 1

Views: 1856

Answers (1)

jewelsea
jewelsea

Reputation: 159291

You need to perform the update to the the text area on the JavaFX application thread.

Wrap the call to your listeners in a Platform.runLater call. This will ensure that the listener notifications occur on the JavaFX application thread.

private void propertyChanged(final String propertyName) {
  final CortexInspectorEvent event = new CortexInspectorEvent(this);
  final Iterator i = this.listeners.iterator();
  while (i.hasNext()) {
    final ICortexInspectorEventListener listener = (ICortexInspectorEventListener) i.next();
    Platform.runLater(new Runnable() {
      @Override public void run() {
        listener.onProperpertyChanged(event, propertyName);
      }
    });
  }
}

For Java8 you could just write:

Platform.runLater(() -> listener.onProperpertyChanged(event, propertyName));

The reason why your try catch logic doesn't seem to work is because the exception is being raised on the JavaFX application thread which is not thread which is executing the try catch code.

Are you writing a brain scanner or something ;-)

Upvotes: 1

Related Questions