2

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?

Community
  • 1
  • 1
Mulgard
  • 9,877
  • 34
  • 129
  • 232

1 Answers1

2

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)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Problem is... if i dont use the CountDownLatch the done() method of my swingworker is called too early...... – Mulgard Aug 17 '13 at 15:15
  • I'm sure that util.Timer & invokeLater or SwingTimer do that, I'm quite sure that SwingWorker coudl be better for ChatsRoom, JDBC, FileIO, ServerSocket, Cobra etc, not as for timer for game engine, – mKorbel Aug 17 '13 at 15:18
  • so what is better for game engine? – Mulgard Aug 17 '13 at 15:20
  • Also, probably needs `super.paintComponent()` as discussed [here](http://stackoverflow.com/q/7213178/230513). – trashgod Aug 17 '13 at 15:20
  • so what is better for game engine? util.Timer & invokeLater , for lightweight to use only swing.Timer, depands of if is standlalone without any connection, communication out of PC (swing.Timer) or not there is active whatever that can notify Swing GUI from outside (util.Timer) – mKorbel Aug 17 '13 at 15:24
  • @Marc Tigges you can to test, so confortly use paintImmediatelly for painting out of EDT (note on EDT caused exception from RepaintManager, inside loop current JVM could be addept for killing from TaskManager only) – mKorbel Aug 17 '13 at 15:27
  • i dont get it! i have to wait until all my timers have done there work! so if i dont do it in swingworker the lock.await() will freeze the gui! putting lock.await() into invokeLater() also freezes gui – Mulgard Aug 17 '13 at 15:34
  • I agree with mKorbel that using SwingWorker just to block while waiting for the animation to end is misuse. You should arrange for the last animation step to trigger the post-animation actions. – Marko Topolnik Aug 17 '13 at 15:40
  • so how can i wait for the timers without freezing gui? – Mulgard Aug 17 '13 at 15:42
  • The whole concept of waiting is something you have no need for. Just let the action proceed naturally at the end of the last Timer's handler. – Marko Topolnik Aug 17 '13 at 16:07
  • [see my crazy implementations Executor & SwingWorker & Thread#sleep & SwingTimer](http://stackoverflow.com/questions/6171414/how-to-share-data-with-two2-swingworker-class-in-java/6174462#6174462) – mKorbel Aug 17 '13 at 16:10