在容器周围移动标签时在JavaFX上发生异常。(IndexOutOf边界异常)

我正在用JavaFX开发一个游戏,其中角色自行移动,但是,由于某种原因,他们移动了一段时间(似乎也是随机的),然后我得到了以下异常:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 8
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:373)
    at java.base/java.util.ArrayList.get(ArrayList.java:427)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
    at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1704)
    at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1648)
    at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
    at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
    at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
    at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
    at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
    at javafx.graphics/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3289)
    at javafx.graphics/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
    at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
    at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:115)
    at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3844)
    at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3806)
    at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3754)
    at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3908)
    at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3700)
    at javafx.graphics/javafx.scene.Node.updateBounds(Node.java:762)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1835)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1833)
    at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2491)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:413)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:412)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:439)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:563)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:543)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:536)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:342)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:832)

另外,由于某种原因,消息的长度会发生变化,就像抛出以下内容一样:

Index -1 out of bounds for length 1

然后是这个:

Index -1 out of bounds for length 3

以此类推.

我不太理解,因为我正确地使用了游戏角色的Arraylist,将它们用作线索:

public void startTroops(){

        for (GameCharacter gameCharacter : army) {
            gameCharacter.start();
        }
    }

以下代码是线程的run()方法,以及使标签在其容器窗格中随机移动的moveTroops()方法:

   @Override
    public void run() {

        System.out.println(""+ getX() + getY());
        while (running) {
            try {
                refController.moveTroops(this);
                Thread.sleep(1000);
            } catch (InterruptedException ex) {}

            while (paused && running) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {}
            }
        }
    
    public void moveTroops(GameCharacter unit){

        double x = unit.getX();
        double y = unit.getY();
        int direction= ThreadLocalRandom.current().nextInt(0, 3);

        switch (direction){
            case 0: // up
                if (y >= 100) y -= 50;
                break;

            case 1: // down
                if (y <= 900) y += 50;
                break;

            case 2: // left
                if (x >= 100) x -= 50;
                break;

            case 3: // right
                if (x <= 900) x += 50;
                break;
        }

        if (posIsAvailable(x, y)){
            System.out.println(String.format(unit.getunitName() + ": walking (%s, %s)", x, y));
            unit.getSprite().relocate(x, y);
        }
    }

对于该错误是从何而来,是否有明确的原因? 提前感谢!


解决方案

您正在工作线程中四处移动标签?
这很可能是由于没有更新JavaFX平台线程上的UI元素造成的。 考虑使用动画计时器更新游戏状态。目前,请查看当您包装对:

的调用时,问题是否会消失
unit.getSprite().relocate(x, y);

如下:

int newX = x; // need to be effectively final
int newY = y; // for the runLater
Platform.runLater(() -> { unit.getSprite().relocate(newX, newY); });

相关文章