| Here we use a thread to control the display of a clock. We use 
              the Runnable 
              interface with the run() 
              method to control a call to repaint() 
              for the panel that displays the clock value. (We will discuss the Date 
              and DateFormat 
              classes in Chapter 10: Java) Note that repaint() 
              does not immediately initiate a change in the display but rather 
              puts a request on a queue in the AWT graphics system. This approach 
              avoids interference with other graphics tasks occurring.  Do not call paintComponent() 
              directly.   
              
                 
                  | ClockApplet.java 
                      DataFormatPanel.java
 |   
                  | import 
                      javax.swing.*;import java.awt.*;
 
 /**
 * This applet implements Runnable and uses a 
                      thread
 *   to create a digital clock.
 **/
 public class ClockApplet extends JApplet
 implements Runnable {
 // Will use thread reference as a flag
 Thread fThread = null;
 
 // Need panel reference in run ().
 DateFormatPanel fClockPanel = null;
 
 public void init () {
 Container content_pane = getContentPane 
                      ();
 
 // Create an instance of the time 
                      panel
 fClockPanel = new DateFormatPanel 
                      ();
 
 // Add the time panel to the applet's 
                      panel.
 content_pane.add (fClockPanel);
 } // init
 
 // This method called by browser when web page 
                      and
 // applet loaded.
 public void start () {
 // If the thread reference not null 
                      then a
 // thread is already running. Otherwise, 
                      create
 // a thread and start it.
 if (fThread == null){
 fThread 
                      = new Thread (this);
 fThread.start 
                      ();
 }
 } // start
 
 // This method called by browser when web page 
                      and
 // applet loaded.
 public void stop () {
 // Setting thread to null will cause 
                      loop in
 // run () to finish and kill the 
                      thread.
 fThread = null;
 } // stop
 
 public void run () {
 // Loop through sleep periods until
 // thread stopped by setting thread
 // reference to null.
 while (fThread != null) {
 try{
 Thread.sleep 
                      (1000);
 } catch  (InterruptedException 
                      e) { }
 
 // Repaint clock
 fClockPanel.repaint 
                      ();
 }
 } // run
 
 } // class ClockApplet
 |   
                  | import 
                    javax.swing.*; import java.awt.*;
 import java.text.*;
 import java.util.*;
 
 /**
 * This JPanel subclass uses the DateFormat class
 * to display the current time.
 **/
 class DateFormatPanel extends JPanel {
 DateFormat fDateFormat = null;
 boolean fFirstPass = true;
 int fMsgX = 0, fMsgY = 0;
 Font fFont = new Font ("Serif", Font.BOLD, 24);
 
 /** Get the DateFormat object with the default 
                    time style. **/
 DateFormatPanel () {
 fDateFormat =
 DateFormat.getTimeInstance 
                    (DateFormat.DEFAULT);
 } // ctor
 
 /** Draw the time string on the panel center. 
                    **/
 public void paintComponent (Graphics g) {
 super.paintComponent (g);
 
 // Get current date object
 Date now = new Date ();
 
 // Format the time string.
 String date_out = fDateFormat.format 
                    (now);
 
 // Use our choice for the font.
 g.setFont (fFont);
 
 // Do the size and placement calculations 
                    only for the
 // first paint  (assumes 
                    the applet window is never resized.)
 if (fFirstPass) {
 
 // Get measures needed 
                    to center the message
 FontMetrics fm = g.getFontMetrics 
                    ();
 
 // How many pixels wide 
                    is the string
 int msg_width = fm.stringWidth 
                    (date_out);
 
 // Use the string width 
                    to find the starting point
 fMsgX = getSize ().width/2 
                    - msg_width/2;
 
 // How far above the baseline 
                    can the font go?
 int ascent = fm.getMaxAscent 
                    ();
 
 // How far below the baseline?
 int descent= fm.getMaxDescent 
                    ();
 
 // Use the vertical height 
                    of this font to find
 // the vertical starting 
                    coordinate
 fMsgY = getSize ().height/2 
                    - descent/2 + ascent/2;
 }
 g.drawString (date_out,fMsgX,fMsgY);
 fFirstPass = false;
 } // paintComponent
 
 } // class DateFormatPanel
 |  
   Latest update: Nov. 5, 2004 |