【问题标题】:JavaFX throws ArrayIndexOutOfBoundsExceptionJavaFX 抛出 ArrayIndexOutOfBoundsException
【发布时间】:2019-06-14 22:57:54
【问题描述】:

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

'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]

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

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");
}

【问题讨论】:

  • 因为我的代码不涉及意味着你可以发布相同的代码,没有代码参与,不会抛出空指针
  • 这通常发生在尝试从 JavaFX UI 线程以外的线程更改绑定到节点的ObservableList 时,或者在更改期间操作列表时。在这两种情况下,通常将有问题的调用包装在 Platform.runLater 中可以解决问题。参见例如this related question.
  • @RahulSingh:是的,当然,我的代码肯定会导致问题;)但是,它不涉及异常
  • 在什么情况下会调用方法processBacklogGroupList?是否有可能在更改发生时调用它?
  • ArrayList 不是线程安全的

标签: java exception javafx


【解决方案1】:

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

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

感谢@sillyfly 指出真正的问题

这通常发生在尝试更改绑定到的 ObservableList 时 来自 JavaFX UI 线程以外的线程的节点,或者当 在更改期间操纵列表。在这两种情况下通常包装 Platform.runLater 中的违规调用解决了这个问题。参见例如 这个相关的问题。 – sillyfly 6 月 27 日 10:03"

【讨论】:

【解决方案2】:

我遇到了这个问题,由 Platform.runLater(() -> {//your code});

【讨论】:

    猜你喜欢
    • 2016-11-09
    • 2023-03-16
    • 2012-04-12
    • 2013-05-10
    • 1970-01-01
    • 2020-02-07
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多