简体   繁体   中英

Java Getting IndexOutOfBoundsException on different indexes randomly

I have 2 clients connected to a server, they send new coordinates or spawn new circles and the server updates the position of the circles or creates new ones and draw them. I use a timertask with a delay of 5 seconds and a 5 seconds interval to spawn new circles.

I keep getting IndexOutOfBoundsException at random indexes every time i run the application when i setTranslateX.

private void updateSimulation(ArrayList<String> cl) {
    if(cl == translatedCoorsMessage) {
        Platform.runLater(() -> {
            int x= 1;
            for(Circle circle : circlesOnCorridorOfClient) {
                circle.setTranslateX(((Double.parseDouble(cl.get(x))) - 20.0)/1000);
                x=x+2;
            }
            circlesOnCorridorOfClient.addAll(newCirclesToAddOnCorridor);
            newCirclesToAddOnCorridor.clear();
        });
    }
    else {
        Platform.runLater(() -> {
            int x= 1;
            for(Circle circle : circlesOnCorridorOfClient1) {
                circle.setTranslateX(((Double.parseDouble(cl.get(x))) - 967.0)/1000);
                x=x+2;
            }
            circlesOnCorridorOfClient1.addAll(newCirclesToAddOnCorridor1);
            newCirclesToAddOnCorridor1.clear();
        });
    }
}

This error can happen after the second circle spawns or third or the 5th, etc. I set my x = 1 because the first element in the ArrayList i pass to this method is just a small String to know what i will do with the ArrayList. In this case, update. the second is X coordinate and third is Y. It feels like the foreach loop runs one extra time some times after i add a new circle. I only add new circles after the loop and i do it through another arraylist.

Any tips will be apreciated. thanks for your time.

Im not sure but i think that the problem is that everything i did in Platform.runLater happens in another thread (Application Thread). So my server was updating and adding new circles(this circles are added in a separate ArrayList to avoid ConcurrentModificationException) then i add my new circles to the main ArrayList after i update every circle position. So that was the problem, for a moment i had 1 extra circles.

I "fixed" this problems by adding 2 volatile integers in my Server. i used those integers to check if im done doing everything in Platform.runLater. the server stays in a while loop that does nothing, just waiting until the Platform.runLater part is done and changes the value of this integers so that Server Thread can exit this while loop and continue. I dont get the IndexOutOfBoundsException any more but the "animation" is really slow.

private void updateSimulation(ArrayList<String> cl) {
    if(cl == translatedCoorsMessage) {
        Platform.runLater(() -> {
            int x= 1;
            for(Circle circle : circlesOnCorridorOfClient) {
                circle.setTranslateX(((Double.parseDouble(cl.get(x))) - 20.0)/1000);
                x=x+2;
            }
            circlesOnCorridorOfClient.addAll(newCirclesToAddOnCorridor);
            newCirclesToAddOnCorridor.clear();
            testtest = 1;
        });
        while(testtest == 0){
            //waiting
        }
        testtest = 0;
    }
    else {
    Platform.runLater(() -> {
        int x= 1;
        for(Circle circle : circlesOnCorridorOfClient1) {
            circle.setTranslateX(((Double.parseDouble(cl.get(x))) - 967.0)/1000);
            x=x+2;
        }
        circlesOnCorridorOfClient1.addAll(newCirclesToAddOnCorridor1);
        newCirclesToAddOnCorridor1.clear();
        testtest1 = 1;
    });
            while(testtest1 == 0){
                //waiting
            }
            testtest1=0;
    }
}

is an ugly solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM