/*
 * ExceptionsDemo2.java - demonstration of exception propagation
 *
 * This program asks the user to enter an arithmetic expression consisting
 * of two numbers plus one of the operations +, -, *, or /.  The method
 * evaluateExpression will throw an exception if divide by zero is attempted,
 * and will propagate exceptions in the case of malformed numbers.
 *
 * Copyright (c) 2000, 2004, 2008 - Russell C. Bjork
 *
 */
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ExceptionsDemo2 extends JFrame implements ActionListener
{
    /** Main method for the program
     */
    public static void main(String [] args)
    {
        new ExceptionsDemo2().setVisible(true);
    }
    
    /** Constructor - create the GUI 
     */    
    public ExceptionsDemo2()
    {
        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints(
            0, GridBagConstraints.RELATIVE, 1, 1, 0, 0,
            GridBagConstraints.CENTER, GridBagConstraints.NONE,
            new Insets(10, 10, 10, 10), 0, 0);

        number1Prompt = new JLabel("Please enter first number");
        getContentPane().add(number1Prompt, constraints);
        
        number1Input = new JTextField(20);
        getContentPane().add(number1Input, constraints);
        
        number2Prompt = new JLabel("Please enter second number");
        getContentPane().add(number2Prompt, constraints);
        
        number2Input = new JTextField(20);
        getContentPane().add(number2Input, constraints);
        
        operation = new JComboBox();
        operation.addItem("+"); 
        operation.addItem("-"); 
        operation.addItem("*"); 
        operation.addItem("/");
        getContentPane().add(operation, constraints);
        
        evaluateButton = new JButton("Evaluate");
        getContentPane().add(evaluateButton, constraints);
        
        result = new JLabel(" ");
        getContentPane().add(result, constraints);
        
        // Prepare to handle mouse click on the evaluate button
        
        evaluateButton.addActionListener(this);
        
        pack();
    }
      
    /** Method invoked when the user clicks the compute button */
    
    public void actionPerformed(ActionEvent e)
    {
        try
        {
            double value = evaluate(number1Input.getText(),
                                    number2Input.getText(),
                                    ((String) operation.getSelectedItem()).charAt(0));
            result.setText("Result = " + value);
            result.setForeground(Color.black);
       }
        catch(NumberFormatException exception)
        {
            result.setText("Please enter two number");
            result.setForeground(Color.red);
            return;
        }
        catch(ArithmeticException exception)
        {
            result.setText("Arithmetic error: " + exception.getMessage());
            result.setForeground(Color.red);
            return;
        }
    }
    
    /** Evaluate a simple arithmetic expression
     * 
     *  @param number1 the first number as typed by the user
     *  @param number2 the second number as typed by the user
     *  @param operation the operation
     *  @return the result of applying operation to number1 and number2
     *  @exception NumberFormatException if either number is malformed
     *  @exception ArithmeticException if there is an arithmetic error (e.g. divide
     *             by zero) in the operation
     */
    private double evaluate(String number1, String number2, char operation)
                                throws NumberFormatException, ArithmeticException
    {
        double value1 = Double.parseDouble(number1);
        double value2 = Double.parseDouble(number2);
        switch(operation)
        {
            case '+': 
                return value1 + value2;
            case '-': 
                return value1 - value2;
            case '*': 
                return value1 * value2;
            case '/': 
                if (value2 == 0)
                    throw new ArithmeticException("/ by 0");
                else
                    return value1 / value2;
            default: return 0;  // To keep the compiler happy
        }
    }
   
    // Instance variables - components of the GUI
    
    private JLabel number1Prompt;
    private JTextField number1Input;
    private JLabel number2Prompt;
    private JTextField number2Input;
    private JComboBox operation;
    private JButton evaluateButton;
    private JLabel result;
}
