0

Thread.sleep() always pauses JFrame before the sleep() statement even gets executed. I have the following method to pause the thread:

private void sleep(int milli)   {
    try {
        Thread.sleep(milli);
    }   catch   (InterruptedException ex)   {
        writeToConsoleError("Interrupted");
    }
}

I'm calling it in the following switch-case statement under case CARDNOMATCH:, this method is in a class which extends JFrame.

public void handlePacket(Packet recieved)   {
    int cmd = recieved.getCommand();
    int arg1 = -99;
    int arg2 = -99;
    switch (cmd)    {
        case CARDNOMATCH:
            arg1 = recieved.getFirstArg();
            arg2 = recieved.getSecondArg();
            if(arg1 > 9)    {
                arg1 = 9;
            }
            if(arg2 > 9)    {
                arg2 = 9;
            }
            flipCard(choice1, arg1);
            flipCard(choice2, arg2);
            sleep(3000);
            flipCard(choice1, 10);
            flipCard(choice2, 10);
            break;
        case ENABLE_TURN:
            this.isTurn = true;
            break;
        case DISABLE_TURN:
            this.isTurn = false;
            break;
    }
}

Please, anyone, give me some insight :(

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
noobcoder
  • 323
  • 1
  • 3
  • 12
  • 1
    Are you sleeping in the event thread? That'll freeze your GUI, which is not what you want. – Kayaman Mar 30 '17 at 06:15
  • 2
    1) Don't block the EDT (Event Dispatch Thread). The GUI will 'freeze' when that happens. See [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for details and the fix. 2) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Mar 30 '17 at 06:18
  • @Kayaman yup, its inside a method which is called by actionlistener. How would I still wait 3 seconds without having it in an event? – noobcoder Mar 30 '17 at 06:18
  • 1
    Start a `SwingWorker` (which will run in not EDT), have *that* sleep 3 seconds, then perform some action (possibly with `invokeLater()`). – Kayaman Mar 30 '17 at 06:20
  • You want to step back and read about the threading model to be used when dealing with Swing UIs. See the duplicated question; and probably http://stackoverflow.com/questions/7217013/java-event-dispatching-thread-explanation too – GhostCat Mar 30 '17 at 06:26

1 Answers1

3

UI is not updated instantaneously.

When you call

flipCard(choice1, arg1);
flipCard(choice2, arg2);

I assume flipCard updates the UI in some way. And your expected behaviour is that choice1 and choice2 cards will be flipped, wait 3 seconds, and flip them again. But the actual behaviour you get is that nothing happens until 3 seconds have passed, after 3 seconds, the cards flipped twice.

What you need to understand is that UI has a frame rate. When you call flipCard, the card will not be flipped until the next frame. During the time between this frame and the next, Thread.sleep is called so everything, including the frames, pause for 3 seconds. That's why the UI updated after 3 seconds' pause.

I suggest you to use javax.swing.Timer or javax.swing.SwingWorker. See here or here for more info.

Sweeper
  • 213,210
  • 22
  • 193
  • 313