-1

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.

CCBoy
  • 29
  • 4
  • 1
    The error is that `cl.get(x)` is sometimes invalid. Even *without considering concurrency issues* and modifying a shared ArrayList, this failure seems "expected" because there is no valid logic determining that `x` is valid or otherwise limiting it to a valid range - how *many* items are in `cl` when the error occurs? It is less than is being expected. -- The error has nothing to do with "setTranslateX" which might as well be replaced with "println". And, if this `Platform.runLater` runs on a *different thread* there may be additional Thread Safety violations. – user2864740 Dec 26 '17 at 05:54
  • Also note that `==` in `cl == translatedCoorsMessage` is *suspicious* –  Dec 26 '17 at 06:08
  • What are the 'circlesOnCorridorOfClient' and 'circlesOnCorridorOfClient1' if they are fields, then check the other places they can modify. please provide exception tracer or the line number exception occur – janith1024 Dec 26 '17 at 06:40
  • What is the reason for incrementing your index by 2? `x=x+2;` – crazyExplorer Dec 26 '17 at 09:07
  • sorry for the delay answer, was at work. @user2864740 so i should try another approach for updating my circle positions ? i dont really understand what you mean with my cl.get(x) been invalid sometimes. is it that im trying to get a x that is been modify ? – CCBoy Dec 26 '17 at 20:56
  • @RC. what do you mean with "suspicious"? is there a better way to check which arraylist im passing ? – CCBoy Dec 26 '17 at 21:08
  • @janith1024 those are arraylists of circles. the only place I modify them are in that method. – CCBoy Dec 26 '17 at 21:09
  • @crazyExplorer i do +2 every time because i got the x coordinate on the odd indexes in my arraylist cl. – CCBoy Dec 26 '17 at 21:09
  • I mean https://stackoverflow.com/questions/7520432/what-is-the-difference-between-vs-equals-in-java –  Dec 27 '17 at 06:24

1 Answers1

0

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.

CCBoy
  • 29
  • 4