I'm making a javafx gui application/game and need to update character view concurrently. Every move cycle i update the ImageView of the character as follows:
if (inBounds(direction) && !Collisions.collides(newHitbox, hitbox)) {
this.setX(direction.getX() * this.getVelocity() + (int) this.view.getX());
this.setY(direction.getY() * this.getVelocity() + (int) this.view.getY());
this.hitbox.setX(direction.getX() * this.getVelocity() + this.hitbox.getX());
this.hitbox.setY(direction.getY() * this.getVelocity() + this.hitbox.getY());
}
I am using a spritesheet for the illusion of movement, so I update the viewport every four cycles.
For a while everything works fine, but at some point i get the following error :
java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 3
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:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
at javafx.scene.Parent.updateCachedBounds(Parent.java:1701)
at javafx.scene.Parent.recomputeBounds(Parent.java:1645)
at javafx.scene.Parent.doComputeGeomBounds(Parent.java:1498)
at javafx.scene.Parent.access$200(Parent.java:79)
at javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
at com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
at com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
at com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
at javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3289)
at javafx.scene.layout.Region.access$300(Region.java:147)
at javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
at com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
at com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:115)
at javafx.scene.Node.updateGeomBounds(Node.java:3837)
at javafx.scene.Node.getGeomBounds(Node.java:3799)
at javafx.scene.Node.updateBounds(Node.java:771)
at javafx.scene.Parent.updateBounds(Parent.java:1832)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2497)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:412)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:411)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:438)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:519)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Thread.java:834)
Because this deosn't happen consistently I assume that at some point the threads try to access the parent of their ImageView at the same time and something breaks.
I was unable to localize the error as the error message doesn't tell me much about where in my code this happens. I tried to make the methods which update the view synchronized as well as the part of the code synchronized with the Parent object as their monitor, but that didn't help at all.
Personally I don't use those Bounds which are getting updated, so if there was a possibility to turn the recomputing off that might do.