// An applet that says "Hello World" in a big bold font.
// The color of the greeting will cycle through the spectrum
// when the user clicks a button and ends when the user clicks
// the button again.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class HelloWorldSpectrum extends JApplet {


   Display display;  // A JPanel belonging to the nested "Display"
                     // class; used for displaying "Hello World."
   
   JButton startStopButton; // The button that will be used to 
                            // start and stop the animation.

   Timer timer;  // The timer that drives the animation.  A timer
                 // is started when the user starts the animation.
                 // Each time an ActionEvent is received from the
                 // timer, the color of the message will change.
                 // The value of this variable is null when the
                 // animation is not in progress.
                 
   int colorIndex;  // This will be a number between 0 and 100 that
                    // will be used to determine the color.  It will
                    // increase by 1 each time a timer event is
                    // processed.

   public void init() {
          // This is called by the system to initialize the applet.
          // It add a button to the "south" position in the applet's
          // content pane, and it adds a display panel to the "center"
          // position so that it will fill the rest of the content pane.

       display = new Display();
             // The component that displays "Hello World".

       getContentPane().add(display, BorderLayout.CENTER);
             // Adds the display panel to the CENTER position of the
             // JApplet's content pane.

       JPanel buttonBar = new JPanel();
             // This panel will hold the button and appears
             // at the bottom of the applet.
       buttonBar.setBackground(Color.gray);
       getContentPane().add(buttonBar, BorderLayout.SOUTH); 
       
       startStopButton = new JButton("Start");
       buttonBar.add(startStopButton);

       startStopButton.addActionListener( new ActionListener() {
                  // The action listener that responds to the 
                  // button starts or stops the animation.  It
                  // checks the value of timer to find out which
                  // to do.  Timer is non-null when the animation
                  // is running, so if timer is null, the 
                  // animation needs to be started.
             public void actionPerformed(ActionEvent evt) {
                if (timer == null)
                   startAnimation();
                else
                   stopAnimation();
             }
          });

   }  // end init()
   
   ActionListener timerListener = new ActionListener() {
            // Define an action listener to respond to events
            // from the timer.  When an event is received, the
            // color of the display is changed.
         public void actionPerformed(ActionEvent evt) {
             colorIndex++;  // A number between 0 and 100.
             if (colorIndex > 100)
                colorIndex = 0;
             float hue = colorIndex / 100.0F;  // Between 0.0F and 1.0F.
             display.setColor( Color.getHSBColor(hue,1,1) ); 
         }
      };
   

   void startAnimation() {
          // Start the animation, unless it is already running.
          // We can check if it is running since the value of
          // timer is non-null when the animation is running.
       if (timer == null) {
             // Start the animation by creating a Timer that
             // will fire an event every 50 milliseconds, and 
             // will send those events to timerListener.
          timer = new Timer(50, timerListener);
          timer.start();  // Make the time start running.
          startStopButton.setText("Stop");
       }
   }
   

   void stopAnimation() {
         // Stop the animation by stopping the timer, unless the
         // animation is not running.
      if (timer != null) {
         timer.stop();   // Stop the timer.
         timer = null;   // Set timer variable to null, so that we
                         //   can tell that the animation isn't running.
         startStopButton.setText("Start");
      }
   }
   
   
   public void stop() {
         // The stop() method of an applet is called by the system
         // when the applet is about to be stopped, either temporarily
         // or permanently.  We don't want a timer running while
         // the applet is stopped, so stop the animation.  (It's
         // harmless to call stopAnimation() if the animation is not
         // running.)
      stopAnimation();
   }

   
   // ------ A nested class to represent the drawing surface -------

   class Display extends JPanel {
        // This nested class defines a component that displays
        // the string "Hello World".  The color and font for
        // the string are recorded in the variables colorNum
        // and textFont.

      Color color;      // The color in which the message is to
                        // be displayed.  Initially, this is red.
        
      Font textFont;    // The font in which the message is displayed.
                        // A font object represents a certain size and
                        // style of text drawn on the screen.
                        
      Display() {
            // Constructor for the Display class.  Set the background
            // color and assign initial values to the instance
            // variables color and textFont.
         setBackground(Color.black);
         color = Color.red; // Initial color of the message.
         textFont = new Font("Serif",Font.BOLD,36);
             // Create a font object representing a big, bold font.
      }
      
      void setColor(Color color) {
            // This method is provided to be called by the
            // main class when it wants to set the color of the
            // message.  Change the color of the message.
            // Precondition:  Color is not null.
         this.color = color;
         repaint();
      }

      public void paintComponent(Graphics g){
            // This routine is called by the system whenever this JPanel
            // needs to be drawn or redrawn.  It first calls 
            // super.paintComponent() to fill the panel with the
            // background color.  It then displays the message
            // "Hello World" in the proper color and font.
         super.paintComponent(g);
         g.setColor(color);
         g.setFont(textFont);       // Set the font.
         g.drawString("Hello World!", 25,50);    // Draw the message.
      } // end paintComponent

   } // end nested class Display


} // end class HelloWorldJApplet

