Hey I am modifying the class called SimpleBalls
from this answer (the lower one). In the original version all the items in the list are being added by ballsUp.add(new Ball()
before the animation takes place.
However, I want to dynamically add balls depending on some console output happening in another thread. This, of course, leads to comodification as the animation methods and me adding Ball
s will often access the list at the same time.
I tried setting my list to Collections.synchronizedList
but I think it only had an effect to the "upper part" of the program as, just above the BounceEngine
class we have
public List<Ball> getBalls() {
return ballsUp;
}
set up for the iterations and I don't really know how to apply this there. Also, the same applies to synchronized(list)
as neither ballsUp
(which is the "real" List name), Ball
nor getBalls()
can be passed as an argument to synchronized()
.
This is how I am adding new Balls:
Runnable r = new Runnable() {
public void run() {
String s = null;
try {
while ((s = stdInput.readLine()) != null) {
if(s.startsWith("sttest")){
ballsUp.add(new Ball(new Color(random(200)+54, random(200)+54, random(200)+54)));
}
}
}
};
new Thread(r).start();
Removing the ballsUp.add
makes the code code seamlessly.
The rest of the class is pretty much the same, the only major change is the Thread
calling the add
.
UPDATE: I was able to narrow down the problem a bit. No matter with what I "wrap" it, the add
won't work if inside the while ((s = stdInput.readLine()) != null)
. Even when I only run this add
once the ball still won't appear. If I place it below or above the while
statement it works perfectly fine, the thread itself or the try/catch doesn't seem to be the error, it's something with the while
loop (or its condition)
What triggers the error now is the line shown in the screenshot
- but only if the
ballsUp.add(new Ball()
is under the hood of the while loop
Also, SwingUtilities.invokeLater applied to the for
loop in the upper picture results in no ball being drawn at all.