Using a timer to start a SwingWorker?
The task I need to perform involves requesting some data from an external server, performing some (fairly lengt开发者_高级运维hy) processing on the data, and then updating the GUI with the results of the processing. Because the server might be unresponsive, the task is well suited to a SwingWorker: the doInBackground()
method gets the results, and then the done method updates the GUI.
I need this to happen once every few seconds. I know I can just use a while loop and Thread.sleep, and create a new SwingWorker after each sleep. But everything I've read frowns upon using loops and sleep. I'd like to use a timer but:
Using a swing timer seems counterproductive; since they run on the EDT, I would essentially have no reason to use SwingWorker's doInBackground method. If the server were not responsive, the GUI would be unresponsive.
Using a java.util.Timer seems a bit wasteful: it seems to create a background thread for the TimerTask(), and since I am just creating a SwingWorker to do the actual work, I'm essentially creating a background thread that creates another background thread.
Can anybody tell me what's the best solution? I'd like to stick with SwingWorker since it seems ideally suited to the task, but I would like to avoid using a while loop if I can help it.
Thanks
You could use a ScheduledExecutorService:
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
// get a scheduled executor service with one thread
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// schedule the worker at an intervall of 5 seconds
scheduler.scheduleAtFixedRate(myWorker, 0, 5, TimeUnit.SECONDS);
I don't see why you couldn't use a Swing Timer to start a Swing Worker. What have you tried?
I think you're on the right track with SwingWorker. Now you need to look at its publish and process methods. As your processing progresses, you publish() an object from the background thread then the process() method is called on the Swing(EDT) thread so you can update the gui.
This way there aren't a bunch of timers and other threads to coordinate.
The javadocs have a straightforward example with prime numbers: http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
How large is the set of data you are retrieving? If it is fairly small I would completely detach the task of fetching/processing and displaying.
- Use some sort of in memory cache to hold the most recently processed set of data.
- Use a
javax.swing.Timer
to update the GUI with the cached data. - Use a
java.util.Timer
to fetch the data from the database, process it and update the cache. - Be careful of synchronisation issues between the two times on your cache. You don't want your swing timer grabbing data at the same time as the other timer is updating it.
精彩评论