2017-06-27 85 views
0

我正在试验JavaFX标签和组,通过鼠标拖动在屏幕上移动它们。新节点将从某些线程添加到动画组。 但是,有时我会突然发现以下异常 - 我假设某些节点重叠时。但我不知道问题是什么......因为我的代码没有涉及。有谁知道这个例外和根本原因(使用JDK 1.8.0.-112)? 感谢JavaFX抛出ArrayIndexOutOfBoundsException

'JavaFX Application Thread' lambda$main$68 - Thread[JavaFX Application Thread,5,main] threw an uncaught exception: java.lang.ArrayIndexOutOfBoundsException: -1 
    at java.util.ArrayList.elementData(ArrayList.java:418) ~[?:1.8.0_112] 
    at java.util.ArrayList.get(ArrayList.java:431) ~[?:1.8.0_112] 
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89) ~[jfxrt.jar:?] 
    at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.updateCachedBounds(Parent.java:1591) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.recomputeBounds(Parent.java:1535) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388) ~[jfxrt.jar:?] 
    at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078) ~[jfxrt.jar:?] 
    at javafx.scene.Node.updateGeomBounds(Node.java:3579) ~[jfxrt.jar:?] 
    at javafx.scene.Node.getGeomBounds(Node.java:3532) ~[jfxrt.jar:?] 
    at javafx.scene.Node.getLocalBounds(Node.java:3480) ~[jfxrt.jar:?] 
    at javafx.scene.Node.updateTxBounds(Node.java:3643) ~[jfxrt.jar:?] 
    at javafx.scene.Node.getTransformedBounds(Node.java:3426) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.getChildTransformedBounds(Parent.java:1732) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.updateCachedBounds(Parent.java:1596) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.recomputeBounds(Parent.java:1535) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388) ~[jfxrt.jar:?] 
    at javafx.scene.Node.updateGeomBounds(Node.java:3579) ~[jfxrt.jar:?] 
    at javafx.scene.Node.getGeomBounds(Node.java:3532) ~[jfxrt.jar:?] 
    at javafx.scene.Node.getLocalBounds(Node.java:3480) ~[jfxrt.jar:?] 
    at javafx.scene.Node.impl_intersectsBounds(Node.java:5015) ~[jfxrt.jar:?] 
    at javafx.scene.Parent.impl_pickNodeLocal(Parent.java:705) ~[jfxrt.jar:?] 
    at javafx.scene.Node.impl_pickNode(Node.java:4914) ~[jfxrt.jar:?] 
    at javafx.scene.Scene$MouseHandler.pickNode(Scene.java:3899) ~[jfxrt.jar:?] 
    at javafx.scene.Scene$MouseHandler.access$1600(Scene.java:3485) ~[jfxrt.jar:?] 
    at javafx.scene.Scene.pick(Scene.java:1942) ~[jfxrt.jar:?] 
    at javafx.scene.Scene.access$6700(Scene.java:159) ~[jfxrt.jar:?] 
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3799) ~[jfxrt.jar:?] 
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) ~[jfxrt.jar:?] 
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) ~[jfxrt.jar:?] 
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) ~[jfxrt.jar:?] 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381) ~[jfxrt.jar:?] 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) ~[jfxrt.jar:?] 
    at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_112] 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417) ~[jfxrt.jar:?] 
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) ~[jfxrt.jar:?] 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416) ~[jfxrt.jar:?] 
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555) ~[jfxrt.jar:?] 
    at com.sun.glass.ui.View.notifyMouse(View.java:937) ~[jfxrt.jar:?] 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) ~[jfxrt.jar:?] 
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) ~[jfxrt.jar:?] 
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_112] 

我认为,它是与添加方法的标签(= BorderPane)。我介绍它是为了缩短Java FX应用程序线程处理时间。这有什么问题吗?

private Queue<BacklogGroupAction> todoList = new ConcurrentLinkedQueue<>(); 

class BacklogGroupAction { 
    boolean add; 
    boolean visibleState; 
    BorderPane dv; 

    public BacklogGroupAction(boolean add, boolean visibleState, BorderPane dv) { 
     this.add = add; 
     this.visibleState = visibleState; 
     this.dv = dv; 
    } 

} 

private synchronized void processBacklogGroupList() { 
    if (Platform.isFxApplicationThread()) { 
     while (!todoList.isEmpty()) { 
      BacklogGroupAction p = todoList.poll(); 
      if (p.add) { 
       p.dv.setVisible(p.visibleState); 
       backlogGroup.getChildren() 
       .add(p.dv); 
      } else 
       backlogGroup.getChildren() 
       .remove(p.dv); 
     } 
     backlogGroup.applyCss(); 
     backlogGroup.layout(); 
    } else 
     logger.error("This is not FX Application Thread"); 
} 
+0

,因为我的代码是不参与的手段,你可以发布相同的代码,而无需代码卷入空指针不会被抛出 –

+0

这种试图改变一个'ObservableList'时通常发生绑定到JavaFX UI线程以外的线程的节点,或者在更改过程中操作列表时,通常在“Platform.runLater”中封装有问题的调用可以解决这个问题。 (https://stackoverflow.com/questions/27769583/calling-clear-on-observablelist-causes-indexoutofboundsexception) – Itai

+0

@RahulSingh:是的,当然,我的代码肯定会导致问题;)但是,它并没有涉及在例外情况 – Defarine

回答

1

感谢您的全力帮助。 上面的代码“processBacklogGroupList”实际上是正确的,工作...(所以为什么-1 ..?)

问题是在一个完全不同的地方,一个动画定义不运行在JFX应用程序线程 - 但稍后发生异常。

所以感谢@sillyfly指着我真正的问题

这种试图改变从比JavaFX的UI线程以外的线程绑定到 节点的ObservableList时,要不时 通常发生在更改期间操纵列表。在这两种情况下,通常将 包含在Platform.runLater中的违规呼叫解决了这个问题。见例如 这个相关的问题。 - sillyfly 6月27日在10:03"

+0

请参阅https://bugs.openjdk.java.net/browse/JDK-8163078 如果Oracle会添加一些代码来不抛出Nullpointer异常,出了代码不在JFX主题上的事实。 –

+0

https://stackoverflow.com/a/45679685/1497139有更多链接 –

相关问题