从其他线程进程接收事件后JavaFXUI冻结

从其他线程进程接收事件后JavaFXUI冻结,javafx,Javafx,我是JavaFX新手。我想要实现的只是在控制器从另一个线程接收到事件后更新JavaFX文本区域上的文本。但有时也会有同样的例外 发生的情况如下: Other thread -> Trigger event -> Do proccess at an event handler on JavaFX controller -> Hang with exception. 我总是得到这样的例外: java.lang.ArrayIndexOutOfBoundsException: -1

我是JavaFX新手。我想要实现的只是在控制器从另一个线程接收到事件后更新JavaFX文本区域上的文本。但有时也会有同样的例外

发生的情况如下:

Other thread -> Trigger event -> Do proccess at an event handler on JavaFX controller -> Hang with exception.
我总是得到这样的例外:

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)
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());
        }   
    }
}
我在event类上调用event hendler的代码如下:

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)
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());
        }   
    }
}
即使我放置了try-catch,也不会捕获异常,UI仍然挂起

@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.
}
在我的事件处理程序方法中,即使我放置空方法,UI仍然会挂起

@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.
}

我不知道如何问goo*le这样的问题,我尝试了一堆关键词,但仍然没有得到正确的答案,所以我在这里问。请帮忙。谢谢。

您需要对JavaFX应用程序线程上的文本区域执行更新

将对听众的呼叫包装为呼叫。这将确保侦听器通知发生在JavaFX应用程序线程上

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);
      }
    });
  }
}
对于Java8,您可以编写:

Platform.runLater(() -> listener.onProperpertyChanged(event, propertyName));
您的try-catch逻辑似乎不起作用的原因是,在JavaFX应用程序线程上引发了异常,而该线程不是执行try-catch代码的线程


你是在写一篇文章还是什么;-)

您需要在JavaFX应用程序线程上对文本区域执行更新

将对听众的呼叫包装为呼叫。这将确保侦听器通知发生在JavaFX应用程序线程上

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);
      }
    });
  }
}
对于Java8,您可以编写:

Platform.runLater(() -> listener.onProperpertyChanged(event, propertyName));
您的try-catch逻辑似乎不起作用的原因是,在JavaFX应用程序线程上引发了异常,而该线程不是执行try-catch代码的线程


你是在写一篇文章还是什么;-)

哈哈,我真的很想在将来的某个时候做到。扫描像你这样的人的大脑,并将扫描结果应用到我的大脑,这样我就可以像你一样成为极客了,先生。哈哈。不管怎样,你的解决方案很有魅力。非常感谢你!哈哈,我真的很想在将来的某个时候做到。扫描像你这样的人的大脑,并将扫描结果应用到我的大脑,这样我就可以像你一样成为极客了,先生。哈哈。不管怎样,你的解决方案很有魅力。非常感谢你!