import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/** DemoSwing - simple demo that adds user input to the mix.<p>
*
* This demo goes a step beyond <code>DemoHelloWorld</code> and
* <code>DemoHelloWorld2</code> by adding <i>user interaction</i>.
* The interface presents two GUI buttons.  Clicking on
* one button increments an on-screen counter.
* Clicking
* on the other button terminates the application.<p>
*
* Responding to user input in a GUI application requires a completely
* different approach from console applications.  The program is
* designed to listen for user actions -- clicking on buttons via the
* mouse pointer -- and to respond accordingly.  The approach is called
* <i>event-driven progamming</i>.<p>
*
* However, our main purpose in this demo is to further
* present the organization
* of our program's extended <code>JFrame</code> class when the design
* expands to include additional GUI components and an event-driven
* programming strategy.  (We'll study specific details of event-driven
* programming later. See <code>DemoKeyEvents</code>.)
* <p>
*
* The definition of our extended <code>JFrame</code> -- the application
* window -- is organized as follows:
*
* <ul>
*
* <li>The signature line for the extended <code>JFrame</code>
* declares that it "<code>extends JFrame</code>".<code><code>
* Since it extends <code>JFrame</code>, any
* method that can be on a <code>JFrame</code> can be invoked
* on our extended <code>JFrame</code>.  
* As a convention, our extended <code>JFrame</code> will have
* the same name as the application class, except with "<code>Frame</code>" appended.
* This will
* ensure that the custom class for the application window is unique
* for each demo program.
* Additionally, the
* signature may include clauses such as "<code>implements ActionListener</code>" if
* the application uses an event listener that monitors user interaction
* with buttons, etc.
*
* <li>
* The first order of business within the definition of our
* extended <code>JFrame</code> is to declare
* any variables or components, such as buttons or menu items,
* that must be accessed by more
* than one method.  Generally, these are all <code>private</code>
* members -- accessible only by the methods within our extended
* <code>JFrame</code>.
*
* <li>Then, the constructor is defined.  The constructor has several
* responsibilities which are performed in the
* following order:
*
* <ul>
* <li>declare and initialize local variables,
* <li>construct and
* configure the on-screen
* components for our GUI (buttons, text fields, menus, etc.),
* <li>add any listeners necessary so that user actions on the components are
* sensed and responded to,
* <li>arrange the components in containers
* (instances of <code>JPanel</code>), perhaps
* hierarchically, and, finally,
* <li>make the container at the top of the hierarchy
* the "content pane" for
* our extended <code>JFrame</code>.
* </ul>
*
* <li>Following the constructor, implementations are provided for any
* methods associated with the event
* listeners installed earlier.
*
* <li>Other methods (if any) follow the event listener methods.
*
* <li>Inner classes (if any) appear at the end of our GUI frame.
* </ul>
*
* The statements corresponding to each bullet above are
* identified with comments in the source code (see below).
* <p>
*
* Screen snap (after a few clicks on the "Press me!" button)...<p>
* <center><img src="DemoSwing-1.gif"></center><p>
*
* @see <a href="DemoSwing.java">source code</a>
* @author Scott MacKenzie, 2003
*/
public class DemoSwing
{
   public static void main(String[] args)
   {
      DemoSwingFrame frame = new DemoSwingFrame();
      frame.setTitle("DemoSwing");
      frame.pack();
      frame.show();
   }
}

// -----------------------------
// define the application window
// -----------------------------

class DemoSwingFrame extends JFrame implements ActionListener 
{
   // -----------------------------------------------------------------
   // declare variables and components accessed by more than one method
   // -----------------------------------------------------------------

   private int clickCount;
   private JLabel tally;
   private JButton pressMeButton;
   private JButton exitButton;

   // -----------
   // constructor
   // -----------

   public DemoSwingFrame()
   {
      // --------------------------------------
      // declare and initialize local variables
      // --------------------------------------

      clickCount = 0;

      // -------------------------------
      // create and configure components
      // -------------------------------

      tally = new JLabel("Click count: 0");
      tally.setHorizontalAlignment(SwingConstants.CENTER);
      pressMeButton = new JButton("Press me!");
      exitButton = new JButton("Exit");

      // -------------
      // add listeners
      // -------------

      pressMeButton.addActionListener(this);
      exitButton.addActionListener(this);
      this.addWindowListener(new WindowCloser());

      // ------------------
      // arrange components
      // ------------------

      // put components in a panel

      JPanel panel = new JPanel();
      panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      panel.setLayout(new GridLayout(3, 1));
      panel.add(pressMeButton);
      panel.add(tally);
      panel.add(exitButton); 

      // make the panel this extended JFrame's content pane

      this.setContentPane(panel);
   }

   // -------------------------------
   // implement ActionListener method
   // -------------------------------

   public void actionPerformed(ActionEvent ae)
   {
      if (ae.getSource() == pressMeButton)
      {
         clickCount++;
         tally.setText("Click count: " + clickCount);
      }
      else if (ae.getSource() == exitButton)
         System.exit(0);   
   }

   // -------------
   // other methods
   // -------------

   // (no other methods in this demo program)

   // -------------
   // inner classes
   // -------------

   // Note: WindowAdapter implements WindowListener

   private class WindowCloser extends WindowAdapter
   {
      public void windowClosing(WindowEvent event)
      {
         System.exit(0);
      }
   }
}

