質問

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?

役に立ちましたか?

解決

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)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top