Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Thread.sleep question

 
richard rehl
Ranch Hand
Posts: 36
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Modifying an exercise in Deitel (Java How to program) and can't get Thread.sleep to work. The exercise was to create a square-shaped spiral, which I then modified to run a loop which goes between various numbers of spirals. I know that to slow it down enough that I can see the iterations, I need to use the Thread.sleep() method, yet I can't quite get it working... running the program just causes it to pause until the last screen is drawn. I have tried placing the try/catch block in several different places to no avail.

If you hadn't guessed, I know next to nothing about threads.

Here's the code.>
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"She no work" is not particularly descriptive of the symptoms you believe you're seeing. 50 milliseconds isn't very long; I don't believe that would be slow enough for me.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't sleep in the screen updating thread; it just doesn't work that way. Instead, the way to do animation is to make your paintComponent() method draw your picture based on the current values of some member variables, and then create a separate thread which sets the variables, calls repaint(), and then Thread.sleep(). THen changes the variables to new values (i.e. increments "i") calls repaint() again, then calls Thread.sleep(). And so on.
 
Rob Spoor
Sheriff
Pie
Posts: 20380
46
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Concurrency in Swing.

Moving to Swing as this is a UI question.
 
richard rehl
Ranch Hand
Posts: 36
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I still need help. I tried doing what you suggested, Ernest, and moved the incrementing/variable setting code to a separate method, run(), which calls repaint() and Thread.sleep(). I've screwed something up, though, because I see that all the variables are initialized to 0 when paintComponent() is called. I'm obviously missing something very basic. Revised code:

">
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're getting closer, but there's one thing that still needs attention. You're initializing many of the variables from the return values of getWidth() and getHeight() at the time the JPanel is being constructed. At that time, though, the JPanel isn't on the screen yet; it hasn't been laid out, and so its size hasn't been determined. getWidth() and getHeight() are returning 0!

To fix, you have to delay initializing those variables until the values are available, which won't be until after setVisible() is called and the layout actually occurs. Perhaps it'd be better to provide the expected values in the constructor -- i.e., give DrawSpiral's constructor two int arguments, pass in 400 and 250 from main, and initialize those variable in the DrawSpiral constructor.

That ought to do it , actually! Although I suggested creating a thread to do the animation loop, you're doing it right on the main thread. This is actually fine -- there's nothing wrong with that.
 
richard rehl
Ranch Hand
Posts: 36
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Argghhhh... I'm not going to continue torturing you until I understand this better. I did try adding

to the DrawSpiral constructor, also
, still getting initialized values in paintComponent().
I also moved the variables down below the constructor... but I'm guessing that doesn't make a difference.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I meant something like

 
richard rehl
Ranch Hand
Posts: 36
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all your help... I'm still not quite getting the whole Thread.sleep()/paintComponent() combination, so I'm going to put it on the back burner for the nonce.

I did have a question though... one of the things that I like about my original code was that when I resized the window, the spiral would scale with it. In my naivete, putting

in the paintComponent() method caused this to happen. I'm not understanding exactly what is causing repaint() to fire each time the window is resized - is it the JFrame, the JPanel, or something else?

Here's the original code, FWIW:
>
 
richard rehl
Ranch Hand
Posts: 36
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What a difference a night's sleep makes! I decided to move on to the second exercise, a true spiral, and after solving that, tackled the Thread.sleep() thing again, and got it to work. Please feel free to critique my code!
>
 
pete stein
Bartender
Posts: 1561
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
richard rehl wrote:What a difference a night's sleep makes! I decided to move on to the second exercise, a true spiral, and after solving that, tackled the Thread.sleep() thing again, and got it to work. Please feel free to critique my code!

You still need to read the article linked to above about Concurrency in Swing since you're still calling Thread.sleep on the EDT. Myself, I wouldn't use Thread.sleep or a background thread (at least not directly), but instead would use a Swing Timer.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
pete stein wrote:
You still need to read the article linked to above about Concurrency in Swing since you're still calling Thread.sleep on the EDT. Myself, I wouldn't use Thread.sleep or a background thread (at least not directly), but instead would use a Swing Timer.


No, he's sleeping in main(), which is serving as the animation thread. SwingTimer is an option, but what he's doing here is perfectly fine.
 
pete stein
Bartender
Posts: 1561
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest Friedman-Hill wrote:No, he's sleeping in main(), which is serving as the animation thread. SwingTimer is an option, but what he's doing here is perfectly fine.


I always thought that even if you are in the main, you should do most all of your Swing creation on the EDT; to use his code as an example, something like so:



Please correct me if my conceptions are incorrect.
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic