• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

In the background drawing thread, which is the better option?

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All,

I am programming some games in Swing, everything is good. But in main Loop Drawing Thread. What option should I use?

Basically there are 2 options as far as I know:

1) Swing Timer class, which is easy to help you to setup the repeated thead. But the timer thread also put into the EDT to wait and get executed. Will this potentially block other gui's component, once I heavily draw the graphics and the GUI application get complicated.

2) Use Swingworker, I like the class, but in the definition, it's just for dealing with some heavy loading tasks, is it suitable for drawing all the graphics?

3) Or I may create a seperate thread, which is obviously not thread safe for the application.

Anyway, what's best practise for doing this?

Thanks very much indeed.
 
Saloon Keeper
Posts: 15524
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What you can do is have a BufferedImage field in your class, and when paintComponent() is called, you just draw this image. This should be a fast operation, and your GUI should remain responsive.

In a separate thread (you can use a SwingWorker or a regular thread, it doesn't matter much), you can update the BufferedImage whenever necessary, and then call the repaint() method. Just make sure access to the BufferedImage is mutually exclusive, by synchronizing on it.
 
Sheriff
Posts: 22784
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You don't need to synchronize with SwingWorker, as long as you do any updates to it on the EDT. So in simplified form:
As long as each update gets its own SwingWorker there are no synchronization issues:
- the SwingWorker's image is accessed from two threads (the SwingWorker thread in doInBackground() and the EDT in done()) but done() is guaranteed to run after doInBackground() has finished.
- the ImagePanel's image is accessed from the EDT only.
 
Seabook Chen
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the response guys. I've tries to ask in the IBM java forum, there are no response and IBM forum seems quiet and boring.

So, you guys mean use SwingWorker instead of Swing Timer. Awesome, I will change the code.

Thanks,
Seabook
 
Seabook Chen
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Spoor wrote:You don't need to synchronize with SwingWorker, as long as you do any updates to it on the EDT. So in simplified form:
As long as each update gets its own SwingWorker there are no synchronization issues:
- the SwingWorker's image is accessed from two threads (the SwingWorker thread in doInBackground() and the EDT in done()) but done() is guaranteed to run after doInBackground() has finished.
- the ImagePanel's image is accessed from the EDT only.




But one thing you guys maybe misunderstood is, it's an infinite drawing loop to draw all the gaming backgrounds or updated status image, instead of just load a bunch of images at the very beginning. After all, it's a game, you have to repaint all the stuff time by time.










 
Stephan van Hulst
Saloon Keeper
Posts: 15524
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I guess you can just continuously draw your game scene to a new BufferedImage in your main loop, and when it's done, you pass it to your panel, which then assigns it to a volatile BufferedImage field. Since it is a simple atomic operation, you don't have to worry about synchronization; as long as you don't make changes to the object after you've passed it to the panel.
 
Seabook Chen
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for all the reply.

I just found an awesome Swing Gaming website. I wanna share with you guys, which can help you easily understand how to use swing to build some games.

http://zetcode.com/tutorials/javagamestutorial/

Enjoy reading and happy coding.

Thanks,
Seabook
 
Rob Spoor
Sheriff
Posts: 22784
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Version two:
This time there is even less worry about synchronization; the SwingWorker's BufferedImage is a local variable now, and process(...) is executed on the EDT just like done().
 
Stephan van Hulst
Saloon Keeper
Posts: 15524
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Rob, after process() gets called, does the EDT clear the list of chunks again?

I'm not very familiar with SwingWorker, because it's a 1.6 feature, and my crummy old laptop runs 1.5.
 
Rob Spoor
Sheriff
Posts: 22784
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
publish puts everything into some internal storage. Then once in a while everything that was published is sent as a List to the process method, and the internal storage is emptied. So once an element is sent to process it's gone from the internal storage.

I first fell into the biggest publish-process trap - I assumed that since I published only one element at a time, I would get a List of size 1 each time. Boy was I wrong. But you know what they say about assumptions - it's the mother of all screw-ups.
 
Seabook Chen
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Hey Rob, after process() gets called, does the EDT clear the list of chunks again?

I'm not very familiar with SwingWorker, because it's a 1.6 feature, and my crummy old laptop runs 1.5.



2 main things SwingWorker can do.

1) return the final result, and load some heavy resource.
2) update intermit state, which is very helpful. You could make a progress bar based on that.

Another important thing is, SwingWorker will not block EDT, it's in another thread.

 
Rob Spoor
Sheriff
Posts: 22784
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the doInBackground method at least. done and process are still executed on the EDT.
 
Seabook Chen
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Spoor wrote:Well, the doInBackground method at least. done and process are still executed on the EDT.



Current thread: The execute() method is called on this thread. It schedules SwingWorker for the execution on a worker thread and returns immediately. One can wait for the SwingWorker to complete using the get methods.

Worker thread: The doInBackground() method is called on this thread. This is where all background activities should happen. To notify PropertyChangeListeners about bound properties changes use the firePropertyChange and getPropertyChangeSupport() methods. By default there are two bound properties available: state and progress.

Event Dispatch Thread: All Swing related activities occur on this thread. SwingWorker invokes the process and done() methods and notifies any PropertyChangeListeners on this thread.

doInBackgound is a seperate thread to dealing with heavy task, which is designed for not blocking the EDT, otherwise you won't have a response and interactive UI.

Thanks,
Seabook
 
Stephan van Hulst
Saloon Keeper
Posts: 15524
364
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, I almost forgot. Thanks Rob!
 
Rob Spoor
Sheriff
Posts: 22784
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome
reply
    Bookmark Topic Watch Topic
  • New Topic