在容器周围移动标签时 JavaFX 出现异常。(IndexOutOfBoundsException)
Exception on JavaFX when moving Labels around their container.(IndexOutOfBoundsException)
所以我正在使用 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.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.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(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(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(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();
}
}
下面的代码是线程的运行()方法,以及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); });
所以我正在使用 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.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.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(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(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(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();
}
}
下面的代码是线程的运行()方法,以及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); });