Search code examples
javaswingrepaintswingworkercountdownlatch

Java strange graphics blinking in while lock.await()


i have here a strange behaviour of my graphical user interface. At first here a piece of code:

/**
 * 
 */
@Override
protected Void doInBackground() throws Exception {
    final ModelGameState actualGameState = controller.getActualGameState();
    final ModelCoinState actualCoinState = (actualGameState.getPlayersTurn() == ModelConstants.PLAYER_ONE_ID? actualGameState.getCoinsPlayerOne() : actualGameState.getCoinsPlayerTwo());
    final List<ModelCoinState> temp = MoveCalculator.getMoves(actualCoinState, this.cellID);
    final CountDownLatch lock = new CountDownLatch(temp.size());
    int time = 500;
    
    for(int i = 0; i < temp.size(); i++) {
        final int index = i;
        
        Timer timer = new Timer(time, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(actualGameState.getPlayersTurn() == ModelConstants.PLAYER_ONE_ID) {
                    actualGameState.setCoinsPlayerOne(temp.get(index));
                } else {
                    actualGameState.setCoinsPlayerTwo(temp.get(index));
                }

                controller.setActualGameState(new ModelGameState(actualGameState));
                
                lock.countDown();
            }
        });
        
        timer.setRepeats(false);
        timer.start();
        
        time += 500;
    }
    
    lock.await();

    return null;
}

at second here my gui:

enter image description here

and here my problem: everytime lock.await is called my screen looks like that:

enter image description here

As you can see, behind each of my circles the top left corner of my gui is shown everytime lock.await() is called (At least i think it is when lock.await()is called because when i delete lock.await() i cant see the whole animation of my gui but i also cant see this strange behaviour and that behaviour appears always when the program is through all code of doInBackground().

What causes this strange behaviour?


Solution

  • not an answer only disagree with, my comments against, no reviews, not tried your code, apologize me that there are any reason, maybe my bad

    • doInBackground() is bridge between AWT/Swing EDT and Workers Thread(s), by default never notified EDT

    • process, publish, setProgress and done() notify EDT

    • then Swing Timer inside doInBackground() is against all intentions, why was SwingWorker implemented in official APIs, there is place to execute long running, hard or non_safe code

    • again SwingWorker is designated as bridge between AWT/Swing and Workers Thread(s)

      _____________________________

    there are two ways

    • use CountDownLatch with invokeLater() or Swing Timer. don't mix that together nor from SwingWorker

    • use CountDownLatch, util.Timer, SheduledExecutor with notify EDT by wrap (only relevant, only output, methods will be repainted on the screen) Swing methods to the invokeLater()

    • use only Swing Timer (non_accurate on hour period)