Win a copy of Practical SVG this week in the HTML/CSS/JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Problems with thread sleep and repaint

 
Shafin Jadavji
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm building a blackjack applet game and am having problems with waiting a few seconds before I display each card(a new JLabel with Icon) to the screen. I have a CardPanel class which extends JLayerdPane which I create 2 instances of(one for dealer and one for player) in the main applet. I also have a Thread.sleep(2000) in the updateHand method in the CardPanel (which gets called by a button in the main applet)that I want to wait 2 seonds before creating a new JLabel with an ImageIcon for the players card and then wait another 2 seconds before doing the same for the dealers card. But instead I get a 4 second wait and both cards are drawn at the same time.
As you can tell by the code I'm a java newbie so if I am using thread totally wrong please let me know.

Here's the code for the Applet

I'm not sure how to add the image to this post but any gif should work if renamed to blank.gif or I can email the gif I used.
[ November 10, 2003: Message edited by: Shafin Jadavji ]
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do not, ever, sleep on the event handling thread. If you do, then as you've observed, the screen can't repaint, nor can any events be handled, until the sleep returns.
You seem to be confused about the sleep() method. It is not an instance method. It doesn't cause some other thread to sleep. It causes the thread that calls it to sleep. Even if you "call it" on another thread, it's a static method, and it has no effect on that other thread.
You also seem to be confused about how threads work. Your "run()" method returns immediately, which means that even though you do start a thread, it completes instantly. It never does any work at all. I can't really tell what it is that you're trying to do by creating that other thread, anyway.
Now, what you want to do is (very roughly, you'll need to make various changes to make this work, and I'm not saying that your current code is correct in any particular respect, I'm just starting you on the path) is take the code that's in dealButtonActionPerformed and move it into a Runnable.run() method, and in dealButtonActionPerformed create a Thread to run an instance of that runnable, something like

And updateHand should look a little more like

There are undoubtedly details I've left out, but this should put you on track, anyway.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do not, ever, sleep on the event handling thread. If you do, then as you've observed, the screen can't repaint, nor can any events be handled, until the sleep returns.
You seem to be confused about the sleep() method. It is not an instance method. It doesn't cause some other thread to sleep. It causes the thread that calls it to sleep. Even if you "call it" on another thread, it's a static method, and it has no effect on that other thread.
You also seem to be confused about how threads work. Your "run()" method returns immediately, which means that even though you do start a thread, it completes instantly. It never does any work at all. I can't really tell what it is that you're trying to do by creating that other thread, anyway.
Now, what you want to do is (very roughly, you'll need to make various changes to make this work, and I'm not saying that your current code is correct in any particular respect, I'm just starting you on the path) is take the code that's in dealButtonActionPerformed and move it into a Runnable.run() method, and in dealButtonActionPerformed create a Thread to run an instance of that runnable, something like

And updateHand should look a little more like

There are undoubtedly details I've left out, but this should put you on track, anyway.
 
Shafin Jadavji
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the help. I changed my code and it worked perfectly where each card gets drawn afew seconds after each other. I also went ahead and performed the updateHand method a few more times so I could display the rest of the cards in the player and dealer's hands.
But now I have another question. Is ther a way to know if the cards have been repainted so I can update a status label. I have another class that is the Model (in a MVC design where the previouse Applet is the View) which sends a message (by being observable and the JApplet implementing obeserver) back to the applet, who the winner was. I want to take this message and display it on a JLabel I have on the applet, but I only want to do it after all the cards are drawn. So is there a way to tell if the cards have already been painted before I update the status.
I tried using a
while(whatEverTheUpdateHandThreadIsCalled.isAlive()) {
//do nothing
}
But that brings me back to the same problem I had before in that the Applet waits for the thread to die before it can repaint. So once again I get all the cards drawn at the same time. Remember I want to wait a couple of seconds while drawing each card.
Do you have any ideas on what I can do.
Also I am sorry for posting this on the wrong section of the forum. I guess I should have placed it on the Thread section of the forum.
[ November 11, 2003: Message edited by: Shafin Jadavji ]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!