14.6. (Optional) Animation Using the Timer Class |
Not all source objects are GUI components . The javax.swing.Timer class is a source component that fires an ActionEvent at a predefined rate. Figure 14.16 lists some of the methods in the class.
A Timer object serves as the source of an ActionEvent . The listeners must be instances of ActionListener and registered with a Timer object. You create a Timer object using its sole constructor with a delay and a listener, where delay specifies the number of milliseconds between two action events. You can add additional listeners using the addActionListener method, and adjust the delay using the setDelay method . To start the timer, invoke the start() method. To stop the timer, invoke the stop() method.
The Timer class can be used to control animations. For example, you can use it to display a moving message, as shown in Figure 14.17, with the code in Listing 14.9.
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class AnimationDemo extends JFrame { 6 public AnimationDemo() { 7 // Create a MovingMessagePanel for displaying a moving message 8 add( new MovingMessagePanel( "message moving?" )); 9 } 10 11 /** Main method */ 12 public static void main(String[] args) { 13 AnimationDemo frame = new AnimationDemo(); 14 frame.setTitle( "AnimationDemo" ); 15 frame.setLocationRelativeTo( null ); // Center the frame 16 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17 frame.setSize( 280 , 100 ); 18 frame.setVisible( true ); 19 } 20 21 //Inner class: Displaying a moving message 22 static class MovingMessagePanel extends JPanel { 23 private String message = "Welcome to Java" ; 24 private int xCoordinate = ; 25 private int yCoordinate = 20 ; 26 27 public MovingMessagePanel(String message) { 28 this .message = message; 29 30 // Create a timer 31 Timer timer = new Timer( 1000 , new TimerListener()); 32 timer.start(); 33 } 34 35 /** Paint message */ 36 public void paintComponent(Graphics g) { 37 super .paintComponent(g); 38 39 if (xCoordinate > getWidth()) { 40 xCoordinate = -20 ; 41 } 42 xCoordinate += 5 ; 43 g.drawString(message, xCoordinate, yCoordinate); 44 } 45 46 class TimerListener implements ActionListener { 47 /** Handle ActionEvent */ 48 public void actionPerformed(ActionEvent e) { 49 repaint(); 50 } 51 } 52 } 53 } |
The MovingMessagePanel class extends JPanel to display a message (line 22). This class is declared as an inner class inside the main class because it is only used in this class. Furthermore, the inner class is declared static because it does not reference any instance members of the main class.
An inner class listener is declared in line 46 to listener for ActionEvent . Line 31 creates a Timer for the listener. The timer is started in line 32. The timer fires an ActionEvent every second, and the listener responds in line 49 to repaint the panel. When a panel is painted , its x coordinate is increased (line 42), so the message is displayed to the right. When the x coordinate exceeds the bound of the panel, it is reset to (line 40), so the message continues moving from left to right.
In §13.12, "Case Study: The StillClock Class," you drew a StillClock to show the current time. The clock does not tick after it is displayed. What can you do to make the clock display a new current time every second? The key to making the clock tick is to repaint it every second with a new current time. You can use a timer to control the repainting of the clock with the code in Listing 14.10.
1 import java.awt.event.*; 2 import javax.swing.*; 3 4 public class ClockAnimation extends StillClock { 5 public ClockAnimation() { 6 // Create a timer with delay 1000 ms 7 Timer timer = new Timer( 1000 , new TimerListener()); 8 timer.start(); 9 } 10 11 private class TimerListener implements ActionListener { 12 /** Handle the action event */ 13 public void actionPerformed(ActionEvent e) { 14 // Set new time and repaint the clock to display current time 15 setCurrentTime() 16 repaint(); 17 } 18 } 19 20 /** Main method */ 21 public static void main(String[] args) { 22 JFrame frame = new JFrame( "ClockAnimation" ); 23 ClockAnimation clock = new ClockAnimation(); 24 frame.add(clock); 25 frame.setLocationRelativeTo( null ); // Center the frame 26 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 27 frame.setSize( 200 , 200 ); 28 frame.setVisible( true ); 29 } 30 } |
The program displays a running clock, as shown in Figure 14.18. ClockAnimation extends StillClock and repaints the clock every 1 second triggered by a timer. Line 7 creates a Timer for a ClockAnimation . The timer is started in line 8 when a ClockAnimation is constructed . The timer fires an ActionEvent every second, and the listener responds in line 15 to set a new time and repaint the clock. The setCurrentTime() method defined in StillClock sets the current time in the clock.