1

Code:

@Override
    public void mouseReleased(MouseEvent e) { //when the mouse is pressed
        Point where=e.getPoint();
        int x=(where.x-3)/20+1;
        int y=(where.y-30)/20+1;
        if(x>=1&&x<=30&&y>=1&&y<=30)
        {
            v[x][y]=1-v[x][y];
            repaint();
            try{
            TimeUnit.MILLISECONDS.sleep(300);
            }
            catch(Exception ex){}
            redo();
            repaint();
        }
    }

The paint function is made so that it will show, on screen, all 30x30 elements of the V matrix. The redo function makes some changes (the details are irrelevant) to V.

What i am trying to do is paint the elements of V, but with v[x][y] changed, wait 0.3s, and then paint the elements of V again, but this time after they were changed by the redo function. But the repaint only works the second time, the first time not doing anything.

Sandeep Chatterjee
  • 3,220
  • 9
  • 31
  • 47
  • Use a [javax.swing.Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) if you're looking to so animation. You can see many examples [here](http://stackoverflow.com/a/21871022/2587435) and [here](http://stackoverflow.com/a/21593458/2587435) and [here](http://stackoverflow.com/a/21534549/2587435) and [here](http://stackoverflow.com/a/21801845/2587435) and [here](http://stackoverflow.com/a/21315495/2587435) and [here](http://stackoverflow.com/a/22123304/2587435). Otherwise, post a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Paul Samsotha Apr 09 '14 at 16:20

1 Answers1

1

The sleep will block the event driven thread (EDT) - try not to sleep in the main thread of your application. The EDT will render your frames / dialogs / panels, and will respond to clicks and menus and keyboard entry. It's really important to do only quick tasks on this thread.

How about adding a Timer object to run code later?

  Timer timer = new Timer(300, new ActionListener(){

     @Override
     public void actionPerformed(ActionEvent e) {
         SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
               // runs code on the EDT to edit UI elements (recommended way)
               redo();
               repaint();
            }

         });  
     }
  });
  timer.setRepeats(false);
  timer.start();

So the Timer object will create a new thread, delay for 300 milliseconds, and then call the 'actionPerformed' method. This will happen on the Timer's thread. It's not recommended to change UI elements from any thread except for the EDT, so we use the invokeLater method which causes swing to run the runnable on the EDT itself - so back on the original thread.

Kieveli
  • 10,944
  • 6
  • 56
  • 81