/*
 *  File: Converter.java
 *  Author: Java, Java, Java
 *  Description: This class creates a GUI interface for
 *   the MetricConverter application using the Java Swing
 *   component set. It illustrates the use of some of the
 *   primary components of Swing, including JFrame, JTextField,
 *   JTextArea, and JButton. The top-level window for a Swing
 *   application is a JFrame. The event model for Swing is the
 *   same as that used in JDK 1.1. So to handle action events
 *   for the application, an ActionListener interface is implemented.
 */

import javax.swing.*;             // Packages used
import java.awt.*;
import java.awt.event.*;

public class Converter extends JFrame       
                       implements ActionListener, KeyPadClient 
{ 

    private JLabel prompt = new JLabel("Distance in miles: "); 
    private JTextField input = new JTextField(6);
    private JTextArea display = new JTextArea(1,25);
    private JButton convert = new JButton("Convert!");
    private KeyPad keypad;
  
    /**
     *  Converter() constructor sets the layout and adds
     *  components to the top-level JFrame. Note that components
     *  are added to the ContentPane rather to the JFrame itself.
     *  This version uses a border layout that divides the frame into
     *  three main panels, an input panel, a display panel, and a
     *  control panel, and gives each panel its own layout. The control
     *  panel contains the keypad within it.
     */
    public Converter() 
	 {
	    getContentPane().setLayout(new BorderLayout());
	    keypad = new KeyPad(this);

	    JPanel inputPanel = new JPanel();         // Input panel
	    inputPanel.add(prompt);
	    inputPanel.add(input);
	    getContentPane().add(inputPanel,"North");

	    JPanel controlPanel = new JPanel(new BorderLayout(0, 0));
	    controlPanel.add(keypad, "Center");
	    controlPanel.add(convert, "South");
	    getContentPane().add(controlPanel, "East");

	    getContentPane().add(display,"Center");  // Output display
	    display.setLineWrap(true);
	    display.setEditable(false);

	    convert.addActionListener(this);
	    input.addActionListener(this);
    } // Converter()
  
    /**
     *  actionPerformed() handles all action events for the program.
     *   In this case static methods of the MetricConverter class are
     *   called to perform the conversions requested by the user. The
     *   user's input is taken from a JTextField and the results are
     *   appended to a JTextArea.
     *  @param e -- the ActionEvent which prompted this method call
     */
    public void actionPerformed(ActionEvent e) 
	 {
        double miles = Double.valueOf(input.getText()).doubleValue();
        double km =  miles / 0.62;
        km = Math.round(km * 100 + 0.5)/100.0;
        display.setText(miles + " miles equals " + km + " kilometers\n");
    } // actionPerformed()

    /**
     *  keypressCallback() is called by the KeyPad whenever one of its
     *   keys is pressed. It is a required method of the KeypadClient interface.
     *   Except for the Clear key, all other keypresses are appended to the input textfield.
     *  @param s -- a String represented the key that  was pressed
     */
    public void keypressCallback(String s) 
	 {
        if (s.equals("C"))
            input.setText("");
        else
            input.setText(input.getText() + s);
    }

    /**
     *  main() creates an instance of this (Converter) class and sets
     *   the size and visibility of its JFrame. 
     *  An anonymous class is used to create an instance of the 
     *   WindowListener class, which handles the window close events
     *   for the application.
     */
    public static void main(String args[])
	 {
        Converter f = new Converter();
        f.setSize(400, 300);  
        f.setVisible(true);
        f.addWindowListener(new WindowAdapter() {      // Quit the application
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    } // main()
} // Converter

class KeyPad extends JPanel implements ActionListener
{
 
    private final static int NBUTTONS = 12;  
    private KeyPadClient kpc;      // Owner of the KeyPad
    private JButton buttons[];
    private String labels[] =      // An array of button labels
            { "1","2","3",
              "4","5","6",
              "7","8","9",
              "C","0","." };

    /**
      *  KeyPad() constructor creates the keypad and sets this.kpc
      *   as a reference to its client.
    */
    public KeyPad(KeyPadClient kpc) 
    {
        this.kpc = kpc;
        setLayout(new GridLayout(4,3,1,1));         // Arrange in a grid
        buttons = new JButton[NBUTTONS];            // Create the array itself
        for(int k = 0; k < buttons.length; k++) 
	     {   buttons[k] = new JButton(labels[k]);    //  Create a labeled button
            buttons[k].addActionListener(this);     //  and a listener
            add(buttons[k]);                        //  and add it to the panel
        } // for
    }    

   /**
    *  actionPerformed() handles keypresses on the keypad and
    *   passes the information to the client via the keypressCallback()
    *   method.
    */
    public void actionPerformed(ActionEvent e) 
	 {
        String keylabel = ((JButton)e.getSource()).getText();
        kpc.keypressCallback(keylabel);
    }
}

/*
 *  File: KeyPadClient.java
 *  Description:  Defines the KeyPadClient interface, which
 *   consists of the keypressCallback method. This method
 *   must be implemented by the client. It is the method called
 *   by the KeyPad whenever one of its buttons is pressed.
 */
abstract interface KeyPadClient
{
    public void keypressCallback(String s);
}


