Listing
of Calculator.java
/*==========================================================
Calculator.java
This program simulates the simple 'four-function' calculator (the
sort that can only add, divide, subtract and multiply). Your
will see that although this appears very simple, in fact we
need quite an extensive program to implement it.
The applet simulates the buttons and display of the standard
pocket calculator, and should look like this when executed:
<img src=calculator.gif>
<p>
(If you aren't looking at the HTML version of this file, you won't
see
the picture)
To signal that the user has tried to do something that is
mathematically
impossible (specifically to divide something by zero) this program
uses the mechanism of 'exception throwing'.
The issue of exception handling is covered in more detail later in
the
module; don't worry if it doesn't make much sense at the moment.
Kevin Boone, July 1999
==========================================================*/
import java.applet.Applet;
import java.awt.*;
// We must include java.awt.event.*, as this includes definitions
of the
//?event handling classes,
like ActionEvent
import java.awt.event.*;
/*==========================================================
Calculator class
The Calculator class provides most of the functionality for this
program. After
the definition of Calculator we will define a class called
'DivideByZeroException'
This is a very simple class that will be used to indicate a
division-by-zero
error condition
==========================================================*/
/// QUESTION: why am I specifying 'implements ActionListener,
KeyListener'
///?to this class?
public class Calculator extends Applet implements ActionListener,
KeyListener
{
/*==========================================================
Variables of Calculator class
==========================================================*/
// MAX_INPUT_LENGTH is a constant indicating how large the number
entered by
//?the user can be. A Java
`double' can store a value with a precision of
//?about 17 digits.
Therefore there is no point in allowing the user to
//?enter numbers any bigger
than this.
final int MAX_INPUT_LENGTH = 17;
/*
Display modes
The variable `displayMode' can take one of three values. For ease
of reading
?I have defined three
constants to represent these values. It doesn't matter
?at all what the values of
these constants are (I have used 0, 1 and 2), as
?long as they are all
different.
The displayMode variable indicates what is currently being
displayed. It
?will either be the number
being entered by the user (INPUT_MODE), the
?result of the last
calculation (RESULT_MODE) or an error message
?(ERROR_MODE). This
variable is very important to the correct function of
?the program. For example,
if the user types a digit when the program is
?in INPUT_MODE, the program
should append the digit to the number
?currently in the display.
If in RESULT_MODE or ERROR_MODE, the display
?should be cleared and the
new digit put at the start. In fact,
?many of the methods in
this class behave differently according to the
?value of displayMode
*/
/// QUESTION: why have I defined constants for these values? In
the program
///?I write `if
(displayMode == ERROR_MODE)'; why don't I just write
///?`if (displayMode ==
2)' ?
final int INPUT_MODE = 0;
final int RESULT_MODE = 1;
final int ERROR_MODE = 2;
int displayMode;
// displayLabel is the area of the applet in which all display will
be shown.
//?I have used a Java
`Label' object for this.
Label displayLabel;
// clearOnNextDigit is set to `true' whenever an operator (`+',
'-', etc) is
//?typed. This causes the
next digit entered to be the start of a new number.
boolean clearOnNextDigit;
// lastNumber is the number that was entered by the user before the
last operator.
//?for example, if the user
type '2' followed by '+', then lastNumber will be
//?set to '2'
double lastNumber;
// lastOperator is the operator last typed by the user. If the user
types a
//?'+' sign (or clicks on
the '+' button), then lastOperator is set to
//?'+'. This variable's
value is set to zero to indicate that no operator
//?has been typed yet
char lastOperator;
/*==========================================================
Calculator constructor
This operator (as with all constructors) is executed when the new
object
is created. In this case we create all the buttons (and the panels
that
contain them), then reset the calculator
The layout of buttons in this Applet is quite complex. We have
three groups
of buttons, one for digits, one for operators and one for
'controls'
(`=', `AC' and `C'). I'm not sure `controls' is the right word
here, but
I couldn't think of a better one. So we create three `Panel'
objects
to contain each group of buttons. A Panel is a blank screen area
whose
job is simply to hold other objects. Associated with each Panel is
a
layout manager. The job of the layout manager is to group the
buttons in
the right order. For example, the button panel has a grid of
buttons, with
four rows of three buttons like this:
7?8?9
4?5?6
1?2?3
.?0?+/-
So we set the layout manager for this panel to a new GridLayout
object.
When we create the new GridLayout we specify `new GridLayout(4, 3)'
which means `create a new GridLayout with four rows of three
columns'.
Having created the panels, we add the buttons. Finally we add all
the
panels into a single panel (called `buttonPanel') and add this to
the
applet. We also add the display area.
==========================================================*/
public Calculator()
{
¡¡¡¡¡¡¡¡ super();
¡¡¡¡¡¡¡¡ setLayout (new
BorderLayout());
¡¡¡¡¡¡¡¡ Panel buttonPanel = new
Panel();
¡¡¡¡¡¡¡¡ Panel numberPanel = new
Panel();
¡¡¡¡¡¡¡¡ numberPanel.setLayout(new
GridLayout(4, 3));¡¡¡¡?
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("7"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("8"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("9"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("4"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("5"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel (numberPanel,
new Button("6"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("1"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("2"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("3"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("."), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("0"), Color.blue);
¡¡¡¡¡¡¡¡ addButtonToPanel
(numberPanel, new Button("+/-"), Color.blue);
¡¡¡¡¡¡¡¡ buttonPanel.add(numberPanel);
¡¡¡¡¡¡¡¡ Panel operatorPanel =
new Panel();
¡¡¡¡¡¡¡¡ operatorPanel.setLayout(new
GridLayout(4, 1));?
¡¡¡¡¡¡¡¡ addButtonToPanel
(operatorPanel, new Button("/"), Color.green);
¡¡¡¡¡¡¡¡ addButtonToPanel
(operatorPanel, new Button("*"), Color.green);
¡¡¡¡¡¡¡¡ addButtonToPanel
(operatorPanel, new Button("-"), Color.green);
¡¡¡¡¡¡¡¡ addButtonToPanel
(operatorPanel, new Button("+"), Color.green);
¡¡¡¡¡¡¡¡ buttonPanel.add(operatorPanel);
¡¡¡¡¡¡¡¡ Panel controlPanel =
new Panel();
¡¡¡¡¡¡¡¡ controlPanel.setLayout(new
GridLayout(4, 1));¡¡¡¡
¡¡¡¡¡¡¡¡ addButtonToPanel
(controlPanel, new Button("AC"), Color.cyan);
¡¡¡¡¡¡¡¡ addButtonToPanel
(controlPanel, new Button("C"), Color.cyan);
¡¡¡¡¡¡¡¡ addButtonToPanel
(controlPanel, new Button("="), Color.cyan);
¡¡¡¡¡¡¡¡ buttonPanel.add(controlPanel);
¡¡¡¡¡¡¡¡ displayLabel = new
Label("");
¡¡¡¡¡¡¡¡ displayLabel.setAlignment(Label.CENTER);
¡¡¡¡¡¡¡¡ /// QUESTION: what
does `North' mean here?
¡¡¡¡¡¡¡¡ add(displayLabel,
"North");
¡¡¡¡¡¡¡¡ displayResult(0);
¡¡¡¡¡¡¡¡ add(buttonPanel);
¡¡¡¡¡¡¡¡ addKeyListener(this);
¡¡¡¡¡¡¡¡ requestFocus();
¡¡¡¡¡¡¡¡ // clearAll sets the
variables of the Calculator object to
¡¡¡¡¡¡¡¡ //?initial values (this is the method that is
called
¡¡¡¡¡¡¡¡ //?when the user clicks on the `AC' button
¡¡¡¡¡¡¡¡ clearAll();
}
/*==========================================================
setDisplayString
This method sets the text in the display area to the specified
string.
This hardly needs to be a method at all, as it is so simple.
However,
it is called many many other methods, and using a method for this
function would make it much easier to modify the program if we
chose a
different way to display data. Otherwise, a large number of lines
would
have to be modified.
==========================================================*/
void setDisplayString(String s)
{
¡¡¡¡¡¡¡¡ displayLabel.setText(s);
}
/*==========================================================
getDisplayString
This method gets the text currently in the display area. See the
note for
`getDisplayString' above for details.
==========================================================*/
String getDisplayString ()
{
¡¡¡¡¡¡¡¡ return
displayLabel.getText();
}
/*==========================================================
clearAll
Sets the state of the calculator to the `just switched on' state,
that is,
`0' in the display, ready to input digits, and the last operator
equal to
zero (that is, there is no last operator). This method is called by
the
constructor to initialize the Calculator, and whenever the user
clicks on `AC'
==========================================================*/
void clearAll()
{
¡¡¡¡¡¡¡¡ setDisplayString("0");
¡¡¡¡¡¡¡¡ lastOperator = 0;
¡¡¡¡¡¡¡¡ lastNumber = 0;
¡¡¡¡¡¡¡¡ displayMode =
INPUT_MODE;
¡¡¡¡¡¡¡¡ clearOnNextDigit =
true;
}
/*==========================================================
clearLastEntry
Clears the number currently in the display. This is called when the
user
clicks on the `C' button.
==========================================================*/
void clearLastEntry()
{
¡¡¡¡¡¡¡¡ setDisplayString("0");
¡¡¡¡¡¡¡¡ clearOnNextDigit =
true;
¡¡¡¡¡¡¡¡ displayMode = INPUT_MODE;
}
/*==========================================================
displayResult
Displays the specified number in the display area, and sets the
variables to
indicate that a result is being displayed. Specifically this method
sets
`clearOnNextDigit' to `true'. This means that as soon as the user
types
a digit, the display will be cleared to make space for a new
number.
==========================================================*/
void displayResult(double result)
{
¡¡¡¡¡¡¡¡ setDisplayString(Double.toString(result));
¡¡¡¡¡¡¡¡ lastNumber = result;
¡¡¡¡¡¡¡¡ displayMode =
RESULT_MODE;
¡¡¡¡¡¡¡¡ clearOnNextDigit =
true;
}
/*==========================================================
displayError
Displays the specified error message in the display area, and sets
the
variables to indicate that an error message is being displayed.
Specifically
this method sets `clearOnNextDigit' to `true'. This means that as
soon
as the user types a digit, the display will be cleared to make
space
for a new number.
The displayMode is set to ERROR_MODE to indicate that the display
contains an
error message and not a number. This is important because the user
might
press a button that modifies the current number (like `+/-').
Clearly
we can't change the sign of an error message (or take its square
root, etc).
==========================================================*/
void displayError(String errorMessage)
{
¡¡¡¡¡¡¡¡ setDisplayString(errorMessage);
¡¡¡¡¡¡¡¡ lastNumber = 0;
¡¡¡¡¡¡¡¡ displayMode =
ERROR_MODE;
¡¡¡¡¡¡¡¡ clearOnNextDigit =
true;
}
/*==========================================================
addButtonToPanel
This is a `convenience function', that is, it exists simply to
reduce the
number of lines in the program (and therefore make it more
convenient for the
programmer to manage). This method is called by the constructor to
add
a new button to the display. It sets the buttons colour, and sets
the
key listener and action listener to the appropriate methods (this
has
to be done for every button, as we can't predict which button will
have
the input focus at any given time).
==========================================================*/
void addButtonToPanel(Panel panel, Button button, Color
backgroundColour)
{
¡¡¡¡¡¡¡¡ panel.add(button);
¡¡¡¡¡¡¡¡ button.setBackground(backgroundColour);
¡¡¡¡¡¡¡¡ button.addKeyListener(this);
¡¡¡¡¡¡¡¡ button.addActionListener(this);
}
/*==========================================================
actionPerformed
This method is called whenever the user clicks a button. This
happens
because the method `addButtonToPanel' calls `addActionListener' for
every button. All this method does is pass on the text on the
button to
`processButton'
==========================================================*/
public void actionPerformed (ActionEvent e)
{
¡¡¡¡¡¡¡¡ processButton(e.getActionCommand());¡¡¡¡
}
/*==========================================================
processButton
This method takes action according to the user's input. It is
called from
two other methods: actionPerformed (when user clicks a button) and
keyPressed (when the user presses a key on the keyboard). This
method
examines the text on the button (the parameter `command') and calls
the
appropriate method to process it.
==========================================================*/
void processButton(String command)
{
¡¡¡¡¡¡¡¡ if
(command.equals("0")) addDigit(0);
¡¡¡¡¡¡¡¡ if
(command.equals("1")) addDigit(1);
¡¡¡¡¡¡¡¡ if (command.equals("2"))
addDigit(2);
¡¡¡¡¡¡¡¡ if
(command.equals("3")) addDigit(3);
¡¡¡¡¡¡¡¡ if
(command.equals("4")) addDigit(4);
¡¡¡¡¡¡¡¡ if
(command.equals("5")) addDigit(5);
¡¡¡¡¡¡¡¡ if
(command.equals("6")) addDigit(6);
¡¡¡¡¡¡¡¡ if
(command.equals("7")) addDigit(7);
¡¡¡¡¡¡¡¡ if
(command.equals("8")) addDigit(8);
¡¡¡¡¡¡¡¡ if
(command.equals("9")) addDigit(9);
¡¡¡¡¡¡¡¡ if
(command.equals(".")) addDecimalPoint();
¡¡¡¡¡¡¡¡ if
(command.equals("*")) processOperator('*');
¡¡¡¡¡¡¡¡ if
(command.equals("-")) processOperator('-');
¡¡¡¡¡¡¡¡ if
(command.equals("/")) processOperator('/');
¡¡¡¡¡¡¡¡ if (command.equals("+"))
processOperator('+');
¡¡¡¡¡¡¡¡ if
(command.equals("=")) processEquals();
¡¡¡¡¡¡¡¡ if
(command.equals("+/-")) processSignChange();
¡¡¡¡¡¡¡¡ if
(command.equals("AC")) clearAll();
¡¡¡¡¡¡¡¡ if
(command.equals("C")) clearLastEntry();
}
/*==========================================================
getNumberInDisplay
Returns a double value indicating the number in the display. This
method
should never be called if the display does not contain a number.
When an
error message is being displayed, the value of `displayMode' is
ERROR_MODE,
so this can be used to test whether the display contains a number.
This method is only necessary to make it easier in future if we
decide to
represent data on the display in a different way (i.e., to use a
different
object rather than `Label')
==========================================================*/
double getNumberInDisplay()
{
¡¡¡¡¡¡¡¡ String input =
displayLabel.getText();
¡¡¡¡¡¡¡¡ return
Double.parseDouble(input);
}
/*==========================================================
processLastOperator
Carries out the arithmetic method specified by the last operator,
the last
number and the number in the display.
If the operator causes an error condition (i.e., the user tries to
divide
something by zero), this method can throw an execption.
==========================================================*/
/// QUESTION: if the user clicks on the buttons `2', `+' and `3',
what values
/// will found in the variables `lastOperator' and `lastNumber',
and the
/// variable `numberInDisplay'?
double processLastOperator() throws DivideByZeroException
{
¡¡¡¡¡¡¡¡ double result = 0;
¡¡¡¡¡¡¡¡ double numberInDisplay
= getNumberInDisplay();
¡¡¡¡¡¡¡¡ switch (lastOperator)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡case '*':
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ result =
lastNumber * numberInDisplay;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ break;
¡¡¡¡¡¡¡¡¡¡¡¡case '+':
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ result =
lastNumber + numberInDisplay;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ break;
¡¡¡¡¡¡¡¡¡¡¡¡case '-':
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ result = lastNumber - numberInDisplay;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ break;
¡¡¡¡¡¡¡¡¡¡¡¡case '/':
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ if
(numberInDisplay == 0)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ throw
(new DivideByZeroException());
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ result =
lastNumber / numberInDisplay;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ break;
¡¡¡¡¡¡¡¡ }¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡ return result;
}¡¡¡¡
/*==========================================================
processOperator
Processes the operator most recently typed. All we do is evalute
the
_last_ operator typed (not this one), and store this current
variable
is `lastOperator' so it will get processed when the user types
another
operator, or `='.
==========================================================*/
void processOperator(char op)
{
¡¡¡¡¡¡¡¡ if (displayMode !=
ERROR_MODE)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡double
numberInDisplay = getNumberInDisplay();
¡¡¡¡¡¡¡¡¡¡¡¡if (lastOperator
!= 0)¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ try
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ double
result = processLastOperator();
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ displayResult(result);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ lastNumber
= result;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ catch
(DivideByZeroException e)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ displayError("Division
by zero!");
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡else
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ lastNumber
= numberInDisplay;
¡¡¡¡¡¡¡¡¡¡¡¡clearOnNextDigit
= true;
¡¡¡¡¡¡¡¡¡¡¡¡lastOperator =
op;
¡¡¡¡¡¡¡¡ }
}
/*==========================================================
processEquals
Deals with the user clicking the `=' button. This method finishes
the
most recent calculator. If the displayMode is `ERROR_MODE' (that
is, the
display contains an error message) this method should not do
anything.
==========================================================*/
void processEquals()
{
¡¡¡¡¡¡¡¡ if (displayMode !=
ERROR_MODE)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡try
¡¡¡¡¡¡¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ double
result = processLastOperator();
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ displayResult(result);
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡catch
(DivideByZeroException e)
¡¡¡¡¡¡¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ displayError("Division
by zero!");
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡lastOperator =
0;
¡¡¡¡¡¡¡¡ }
}
/*==========================================================
processSignChange
This method is called when the user clicks on the `+/-' (sign
change)
button. If the number in the display is negative it is converted to
positive.
If the number in the display is positive it is converted to
negative. If
the number in the display is zero, nothing happens (as `-0' is
meaningless).
This method behaves slightly differently depending on what mode the
display is in. If the user is currently entering a number, then it
looks
at the _string_ in the display. If it is displaying a result it
looks at
the _number_ in the display.
==========================================================*/
/// QUESTION: Why is this? Why does this method have to behave
differently
/// depending on whether a result or a new number is in the
display? Hint: it
/// is quite a subtle problem. The program would work correctly
most of the
/// time if we always treated the display as a number.
void processSignChange()
{
¡¡¡¡¡¡¡¡ if (displayMode ==
INPUT_MODE)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡String input =
getDisplayString();
¡¡¡¡¡¡¡¡¡¡¡¡if
(input.length() > 0)
¡¡¡¡¡¡¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ if
(input.indexOf("-") == 0)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ setDisplayString(input.substring(1));
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ else
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ setDisplayString("-"
+ input);
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡ else if (displayMode ==
RESULT_MODE)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡double
numberInDisplay = getNumberInDisplay();
¡¡¡¡¡¡¡¡¡¡¡¡if
(numberInDisplay != 0)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ displayResult(-numberInDisplay);
¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡ // If displayMode is
`ERROR_MODE' then this method should have no
¡¡¡¡¡¡¡¡ //?effect (because you can't change the sign of
an error message!)
}
/*==========================================================
addDigit
This method is called when the user clicks a digit button, or types
a
digit key. If the number currently being entered is less than 17
digits long,
then it adds the new digit to the end of the display.
==========================================================*/
void addDigit(int digit)
{
¡¡¡¡¡¡¡¡ /// QUESTION: what are
the next two lines for?
¡¡¡¡¡¡¡¡ if (clearOnNextDigit)
¡¡¡¡¡¡¡¡¡¡¡¡setDisplayString("");
¡¡¡¡¡¡¡¡ // We have to be
careful to prevent the user entering ugly numbers
¡¡¡¡¡¡¡¡ //?like `000'. If the number in the display is
`0', and the user
¡¡¡¡¡¡¡¡ //?clicks on `0', this display is not changed.
¡¡¡¡¡¡¡¡ String inputString =
getDisplayString();
¡¡¡¡¡¡¡¡ if ((!inputString.equals("0")
|| digit > 0)?&&
inputString.length() < MAX_INPUT_LENGTH)
¡¡¡¡¡¡¡¡¡¡¡¡setDisplayString(inputString
+ digit);
¡¡¡¡¡¡¡¡ displayMode =
INPUT_MODE;
¡¡¡¡¡¡¡¡ clearOnNextDigit =
false;
}
/*==========================================================
addDecimalPoint
Called when the user clicks on the decimal point button. Puts a
decimal
point on the end of the number currently being entered. If the
number
already contains a decimal point, this method should do nothing
(that is, it should be impossible to enter a number like `1.2.3'
==========================================================*/
void addDecimalPoint()
{
¡¡¡¡¡¡¡¡ displayMode =
INPUT_MODE;
¡¡¡¡¡¡¡¡ if (clearOnNextDigit)
¡¡¡¡¡¡¡¡¡¡¡¡setDisplayString("");
¡¡¡¡¡¡¡¡ String inputString =
getDisplayString();
¡¡¡¡¡¡¡¡ // If the input string
already contains a decimal point, don't
¡¡¡¡¡¡¡¡ //?do anything to it.
¡¡¡¡¡¡¡¡ if
(inputString.indexOf(".") < 0)
¡¡¡¡¡¡¡¡¡¡¡¡setDisplayString(new
String(inputString + "."));
}
/*==========================================================
keyPressed
This method is called when the user presses a key, when any button
has the
input focus. This happens because the method `addButtonToPanel'
calls
`addKeyboardListener' for each button that it knows about. However,
this method does nothing in this program, as keyboard input is
handled
in the method `keyTyped'. Because this applet is defined to
`implement
KeyEventHandler' we have to provide this method, even if it does
nothing.
==========================================================*/
public void keyPressed(KeyEvent e)
{
}
/*==========================================================
keyReleased
Called automatically whenever the user presses and then releases a
key. See
note for `keyPressed' for details
==========================================================*/
public void keyReleased(KeyEvent e)
{
}
/*==========================================================
keyTyped
This method is called when the user presses a key, and then
releases it
when any button has the input focus. This happens because the
method
`addButtonToPanel' calls `addKeyboardListener' for each button that
it knows
about.
This method converts the key press to the text of the corresponding
button,
then passes it to processButton to process. For example, if the
user
presses `enter', this should have the same effect as clicking `='.
So this
method calls `processButton' with the text `='. If the user
presses `escape' this should be treated the same as the `C' button.
All other
keys are treated as digits. If the user presses a letter rather
than
a digit, it will still be passed to `processButton', but
processButton
will ignore it.
==========================================================*/
public void keyTyped(KeyEvent e)
{
¡¡¡¡¡¡¡¡ String command;
¡¡¡¡¡¡¡¡ char keyChar =
e.getKeyChar();
¡¡¡¡¡¡¡¡ if (keyChar ==
KeyEvent.VK_ENTER)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡command = new
String("=");
¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡ else if (keyChar ==
KeyEvent.VK_ESCAPE)
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡command = new
String("C");
¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡ else
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡/// QUESTION:
what do these next two lines do?
¡¡¡¡¡¡¡¡¡¡¡¡byte bytes[] =
{(byte)keyChar};
¡¡¡¡¡¡¡¡¡¡¡¡command = new
String(bytes);
¡¡¡¡¡¡¡¡ }
¡¡¡¡¡¡¡¡ processButton(command);
}
} // class
/*==========================================================
DivideByZeroException class
This class is used to indicate that the user has tried to divide a
number
by zero (which is, of course, impossible. The Calculator applet
should
respond by displaying an error message
The issue of exception handling is covered in more detail later in
the
module; don't worry if it doesn't make much sense at the moment.
==========================================================*/
class DivideByZeroException extends Exception
{
¡¡¡¡¡¡¡¡ DivideByZeroException()
¡¡¡¡¡¡¡¡ {
¡¡¡¡¡¡¡¡¡¡¡¡super("Divide
by zero");
¡¡¡¡¡¡¡¡ }
}
|