It can be notice that the actionPerformed() of javax.swing.Timer will be run on EDT(Event Dispatching Thread), such that it can set UI components directly. On the other hand, the TimerTask of java.util.Timer will be run on NON-EDT, it cannot set UI directly. Such that we have to create and invoke another Runnable object later in EDT to set UI components.
The event dispatching thread (EDT) is a background thread used in Java to process events from the Abstract Window Toolkit (AWT) graphical user interface event queue. These events are primarily update events that cause user interface components to redraw themselves, or input events from input devices such as the mouse or keyboard. The AWT uses a single-threaded painting model in which all screen updates must be performed from a single thread. The event dispatching thread is the only valid thread to update the visual state of visible user interface components. Updating visible components from other threads is the source of many common bugs in Java programs that use Swing. ~ Source: Event dispatching thread from Wikipedia.
So, if you want to schedule a task to perform something related to UI, you should use javax.swing.Timer. Otherwise, you can use java.util.Timer.
Example code:
package javatesttimer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.TimerTask; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingUtilities; /** * * @web http://java-buddy.blogspot.com/ */ public class JavaTestTimer { static int counter = 0; static JFrameWin jFrameWindow; /** * @param args the command line arguments */ public static void main(String[] args) { SwingUtilities.invokeLater(runJFrameLater); } //Create Timer of javax.swing.Timer private static void testSwingTimer(){ javax.swing.Timer swingTimer = new javax.swing.Timer( 5000, new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { jFrameWindow.setLabel("testSwingTimer: " + String.valueOf(counter)); counter++; } }); swingTimer.start(); } //Create Timer of java.util.Timer private static void testUtilTimer(){ java.util.Timer utilTimer = new java.util.Timer(); utilTimer.schedule( new TimerTask(){ @Override public void run() { SwingUtilities.invokeLater( new Runnable(){ @Override public void run() { jFrameWindow.setLabel("testUtilTimer: " + String.valueOf(counter)); counter++; } } ); } }, 0, 5000); } static Runnable runJFrameLater = new Runnable() { @Override public void run() { jFrameWindow = new JFrameWin(); jFrameWindow.setVisible(true); testSwingTimer(); //testUtilTimer(); } }; public static class JFrameWin extends JFrame{ JLabel label; public JFrameWin(){ this.setTitle("java-buddy.blogspot.com"); this.setSize(300, 200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); label = new JLabel(); label.setText("un-initialized!"); this.add(label); } public void setLabel(String l){ label.setText(l); } } }
Related:
- SwingUtilities.isEventDispatchThread(), determine if the current thread is an AWT event dispatching thread.
- javax.swing.SwingWorker
No comments:
Post a Comment