JavaFX - rysowanie wielu obiektów będących wątkami

0

Witam. Wciąż pracuję nad programem z tego wątku. Niestety, nie jestem w stanie wymyślić niczego, co byłoby w stanie współpracować z timeline. Postanowiłem napisać metodę ruchu od nowa i stworzyłem coś takiego:

void move()
    {
        if(position_x-ballRadius<=usingMinLimit_x || position_x+ballRadius>=usingMaxLimit_x)
        {
            dx*=-1;
        }

        if(position_y-ballRadius<=usingMinLimit_y || position_y+ballRadius>=usingMaxLimit_y)
        {
            dy*=-1;
        }

        /*if(position_x+ballRadius>=box.getOuterSquareMinX() && position_x-ballRadius<=box.getOuterSquareMaxX() &&
                position_y+ballRadius>=box.getOuterSquareMinY() && position_y-ballRadius<=box.getOuterSquareMaxY() &&
        !isInTheBox) {
            //timeline.pause();
            try {
                wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }*/

        position_x += dx*speed;
        position_y += dy*speed;
        ball.setCenterX(position_x);
        ball.setCenterY(position_y);
    }

A to mam w metodzie run():

while(true)
        {
            synchronized (this) {
                move();
                try {
                    sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

Dla jednej kulki wszystko działa jak należy. Problem pojawia się, gdy kulek jest więcej. W pewnym momencie wszystkie się zatrzymują i program zaczyna sypać wyjątkami:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 2
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 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:1701)
at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1645)
at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1498)
at javafx.graphics/javafx.scene.Parent.access$200(Parent.java:79)
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.access$300(Region.java:147)
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:3837)
at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3799)
at javafx.graphics/javafx.scene.Node.updateBounds(Node.java:771)
at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1832)
at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2497)
at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:412)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:411)
at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:438)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:519)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Thread.java:834)

Wnioskuję, że moje rozwiązanie "nie lubi" wielowątkowości.

Stąd też mam do Was kolejną prośbę o pomoc. Mam jeszcze jeden pomysł: dodać obiekt klasy Canvas, zmienić sporą część kodu i używać GraphicsContext.fillOval(). Czy powyższy kod da się uratować, czy może lepiej od razu przejść do rozwiązania z poprzedniego zdania. Problem tkwi w tym, że nie mogę używać żadnych "automatów" typu timeline, AnimationTimer, itp.

0
kst142 napisał(a):

java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 2

Pobierasz z ArrayListy element o indeksie -1, dla listy o rozmiarze 2. Może masz gdzieś w kodzie .get(x-1) i to jest wykonywane dla x równego 0?

0

Nigdzie w kodzie nie posługiwałem się listą.
Na szczęście problem został już rozwiązany. Temat można zamknąć.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1