This calculator application was built together with the calculator applications
written in vb and java/swing.
They all look and operate similarly, however, I've only
just corrected a "banker's rounding" discrepancy in both this and the
java/swing programs. At the time of writing (30 May 2003) there appear to be no
side-effects from the changes made.
import java.applet.Applet;
import java.awt.*;
import
java.awt.event.*;
import java.text.*;
public class Calculator extends Applet implements ActionListener,
ItemListener,
KeyListener, MouseListener, FocusListener
{
List list;
ScrollPane listScroll;
Checkbox radioBtn[] = new
Checkbox[6];
CheckboxGroup radioGrp;
Label
radioLbl;
Button btn[] = new Button[20];
TextField
txtFld;
boolean calculated;
String lastEntry;
String
currentTotal;
String actualNumber = "";
int lastOperator =
1; //1 for +, 2 for -, 3 for =,4 for x, 5 for ÷
int
decimalPlaces = 2;
DecimalFormat df;
boolean loaded =
false;
public void init()
{
buildGUI();
setDecimalPlaces();
clearAll();
}
private void cancel()
{
displayNumber(currentTotal);
calculated =
true;
setTheFocus();
}
private void clearAll()
{
addToStripList("<Clr> ");
actualNumber =
df.format(Double.parseDouble("0"));
displayNumber(actualNumber);
calculated =
true;
lastEntry =
df.format(Double.parseDouble("0"));
currentTotal =
df.format(Double.parseDouble("0"));
lastOperator =
3;
setTheFocus();
}
private void clearList()
{
list.removeAll();
clearAll();
setTheFocus();
}
private void setDecimalPlaces()
{
String decimals[] =
{"0","0.0","0.00","0.000","0.0000","0.00000"};
df = new
DecimalFormat(decimals[decimalPlaces]);
}
private void setTheFocus()
{
txtFld.requestFocusInWindow();
txtFld.setCaretPosition(txtFld.getText().length());
}
private void addToStripList(String number)
{
int extra = 0;
if(number.length()
> 5) extra = number.length()/2-1;
if(number.length()
> 7) extra += (number.length()-7)/2;
for(int i = 0; i
< 55-number.length()-extra; i++)
{
number = " " + number;
}
list.add(number);
list.select(list.getItemCount()-1);
setTheFocus();
}
private void displayNumber(String anyNumber)
{
for(int i = anyNumber.length(); i < 15;
i++)
{
anyNumber = " " +
anyNumber;
}
txtFld.setText(anyNumber);
setTheFocus();
}
//------------------------------------------VALIDATE/KEYBOARD
ACTIONS
private boolean validKey(char keyPressed)
{
boolean valid = false;
if(keyPressed == '0' || keyPressed == '1' || keyPressed
== '2' ||
keyPressed == '3' ||
keyPressed == '4' || keyPressed == '5'
||
keyPressed == '6' || keyPressed ==
'7' || keyPressed == '8' ||
keyPressed
== '9' || keyPressed == '.')
{
valid = true;
if(calculated)
{
actualNumber =
"";
displayNumber(actualNumber);
calculated = false;
}
if((keyPressed == '.' &&
actualNumber.indexOf(".") > -1)
||
!
checkLength())
{
valid =
false;
}
}
else if(keyPressed == '+')
addNumber();
else if(keyPressed == '-')
subtractNumber();
else if(keyPressed == '*')
multiplyNumber(false);
else if(keyPressed == '/')
divideNumber(false);
else if(keyPressed ==
KeyEvent.VK_ENTER) equals();
else if(keyPressed == 'C' ||
keyPressed == 'c') cancel();
else if(keyPressed == 'A' ||
keyPressed == 'a') clearAll();
else if(keyPressed == 'L'
|| keyPressed == 'l') clearList();
txtFld.setCaretPosition(txtFld.getText().length());
return
valid;
}
private boolean checkLength()
{
boolean OK = true;
if((actualNumber.indexOf(".") > -1
&&
actualNumber.length()
> 12) ||
(actualNumber.indexOf(".") < 0
&&
actualNumber.length()
> 11))
{
OK =
false;
}
return OK;
}
private void errorMessage()
{
clearAll();
displayNumber("error");
setTheFocus();
}
//--------------------------------------------------ACTIONS FOR + - * /
=
private void addNumber()
{
try
{
double decNumber =
Math.abs(Double.parseDouble(calculated?
lastEntry:actualNumber));
String
formattedNumber = df.format(decNumber);
currentTotal =
df.format(Double.parseDouble(currentTotal)+decNumber);
actualNumber = currentTotal;
displayNumber(actualNumber);
addToStripList(formattedNumber + " +");
lastEntry = formattedNumber;
calculated =
true;
lastOperator =
1;
setTheFocus();
if(actualNumber.length() >
14)
{
errorMessage();
}
}
catch(Exception e)
{
errorMessage();
}
}
private void subtractNumber()
{
try
{
double decNumber =
Math.abs(Double.parseDouble(calculated?
lastEntry:actualNumber));
String
formattedNumber = df.format(decNumber);
currentTotal =
df.format(Double.parseDouble(currentTotal)-decNumber);
actualNumber = currentTotal;
displayNumber(actualNumber);
addToStripList(formattedNumber + " -");
lastEntry = formattedNumber;
calculated =
true;
lastOperator =
2;
setTheFocus();
if(actualNumber.length() >
14)
{
errorMessage();
}
}
catch(Exception e)
{
errorMessage();
}
}
private void multiplyNumber(boolean fromEqualsOperater)
{
try
{
boolean zeroNumber =
false;
double decNumber =
Double.parseDouble(actualNumber);
String
formattedNumber = actualNumber;
if((int)
decNumber - decNumber == 0)
{
zeroNumber =
true;
}
if(lastOperator <
4)
{
currentTotal = lastEntry =
formattedNumber;
}
else
if(calculated)
{
currentTotal =
df.format(Double.parseDouble(currentTotal)
*
Double.parseDouble(lastEntry));
}
else if(lastOperator ==
5)
{
currentTotal =
df.format(((long)((Double.parseDouble(currentTotal) / decNumber)
*
Math.pow(10,decimalPlaces) +
0.5))/Math.pow(10,decimalPlaces));
}
else
{
currentTotal =
df.format(((long)((Double.parseDouble(currentTotal) * decNumber)
*
Math.pow(10,decimalPlaces) +
0.5))/Math.pow(10,decimalPlaces));
}
actualNumber =
currentTotal;
displayNumber(actualNumber);
if(!
fromEqualsOperater)
{
if(formattedNumber.length() !=
1)
{
addToStripList(formattedNumber + "
x");
}
else
{
addToStripList(" " +
formattedNumber + " x");
}
}
else
if(zeroNumber && formattedNumber.length() <=
2)
{
addToStripList(formattedNumber +
" ");
}
else
if(zeroNumber && formattedNumber.length() >
2)
{
addToStripList(formattedNumber +
" ");
}
else
{
addToStripList(formattedNumber +
" ");
}
calculated =
true;
lastOperator =
4;
setTheFocus();
if(actualNumber.length() >
14)
{
errorMessage();
}
}
catch(Exception e)
{
errorMessage();
}
}
private void divideNumber(boolean fromEqualsOperater)
{
try
{
boolean zeroNumber =
false;
double decNumber =
Double.parseDouble(actualNumber);
String
formattedNumber = actualNumber;
if((int)
decNumber - decNumber == 0)
{
zeroNumber =
true;
}
if(lastOperator <
4)
{
currentTotal = lastEntry =
formattedNumber;
}
else
if(calculated)
{
currentTotal =
df.format(Double.parseDouble(currentTotal)
/
Double.parseDouble(lastEntry));
}
else if(lastOperator ==
4)
{
currentTotal =
df.format(((long)((Double.parseDouble(currentTotal) * decNumber)
*
Math.pow(10,decimalPlaces) +
0.5))/Math.pow(10,decimalPlaces));
}
else
{
currentTotal =
df.format(((long)((Double.parseDouble(currentTotal) / decNumber)
*
Math.pow(10,decimalPlaces) +
0.5))/Math.pow(10,decimalPlaces));
}
actualNumber =
currentTotal;
displayNumber(actualNumber);
if(!
fromEqualsOperater)
{
if(formattedNumber.length() !=
1)
{
addToStripList(formattedNumber + "
÷");
}
else
{
addToStripList(" " +
formattedNumber + " ÷");
}
}
else
if(zeroNumber && formattedNumber.length() <=
2)
{
addToStripList(formattedNumber +
" ");
}
else
if(zeroNumber && formattedNumber.length() >
2)
{
addToStripList(formattedNumber +
" ");
}
else
{
addToStripList(formattedNumber +
" ");
}
calculated =
true;
lastOperator =
5;
setTheFocus();
if(actualNumber.length() >
14)
{
errorMessage();
}
}
catch(Exception e)
{
errorMessage();
}
}
private void equals()
{
try
{
if(lastOperator !=
3)
{
if(! calculated &&
lastOperator < 3) addNumber();
if(! calculated && lastOperator == 4)
multiplyNumber(true);
if(!
calculated && lastOperator == 5)
divideNumber(true);
addToStripList(currentTotal + "
=");
addToStripList("...
");
lastEntry =
currentTotal;
currentTotal =
df.format(0.0);
calculated =
true;
lastOperator =
3;
setTheFocus();
}
else
{
clearAll();
}
if(actualNumber.length() >
14)
{
errorMessage();
}
}
catch(Exception e)
{
errorMessage();
}
}
//----------------------------------------------------KEYPAD
ACTIONS
public void actionPerformed(ActionEvent ae)
{
for(int i=0; i<=11; i++)
{
if(ae.getSource() ==
btn[i])
{
if(calculated)
{
actualNumber =
"";
displayNumber(actualNumber);
calculated = false;
}
if(ae.getSource() == btn[11]
&& actualNumber.indexOf(".") > -1)
break;
if(checkLength())
{
actualNumber =
actualNumber+btn[i].getLabel();
displayNumber(actualNumber);
setTheFocus();
}
break;
}
}
if(ae.getSource() == btn[12])
multiplyNumber(false);
else if(ae.getSource() == btn[13])
divideNumber(false);
else if(ae.getSource() == btn[14])
subtractNumber();
else if(ae.getSource() == btn[15])
addNumber();
else if(ae.getSource() == btn[19])
equals();
else if(ae.getSource() == btn[16])
cancel();
else if(ae.getSource() == btn[17])
clearAll();
else if(ae.getSource() == btn[18])
clearList();
}
public void itemStateChanged(ItemEvent ie){}
public void
keyTyped(KeyEvent kb){}
public void keyPressed(KeyEvent kb)
{
if(kb.getKeyCode() == 155) kb.consume();
}
public void keyReleased(KeyEvent kb)
{
txtFld.setCaretPosition(txtFld.getText().length());
if(kb.getKeyCode() == 38 && list.getSelectedIndex() !=
0)
{
list.select(list.getSelectedIndex()-1);
}
if(kb.getKeyCode() == 40 &&
list.getSelectedIndex() != list.getItemCount()-1)
{
list.select(list.getSelectedIndex()+1);
}
}
public void focusGained(FocusEvent fe){}
public void
focusLost(FocusEvent fe)
{
if(!loaded)
txtFld.requestFocusInWindow();
loaded = true;
}
//------------------------------------------------MOUSE
ACTIONS
public void mouseClicked(MouseEvent me)
{
for(int i=0; i<radioBtn.length;
i++)
{
if(me.getSource()
== radioBtn[i])
{
radioBtn[i].setState(true);
decimalPlaces = i;
setDecimalPlaces();
clearAll();
break;
}
}
setTheFocus();
}
public void mousePressed(MouseEvent me)
{
if(me.getModifiers() == 4)
me.consume();
setTheFocus();
}
public void mouseReleased(MouseEvent me)
{
setTheFocus();
}
public void mouseEntered(MouseEvent me){}
public void
mouseExited(MouseEvent
me){}
//-----------------------------------------------------------------------
private void
buildGUI()
//BUILD THE GUI
{
Panel outer = new
Panel();
outer.setSize(620,370);
outer.setLayout(new BorderLayout());
Panel outerN = new
Panel();
outerN.setSize(610,10);
outerN.setBackground(SystemColor.control);
Panel outerS =
new Panel();
outerS.setSize(610,10);
outerS.setBackground(SystemColor.control);
Panel outerE =
new Panel();
outerE.setSize(10,350);
outerE.setBackground(SystemColor.control);
Panel outerW =
new Panel();
outerW.setSize(10,350);
outerW.setBackground(SystemColor.control);
outer.add(outerN,BorderLayout.NORTH);
outer.add(outerS,BorderLayout.SOUTH);
outer.add(outerE,BorderLayout.EAST);
outer.add(outerW,BorderLayout.WEST);
Panel mainPanel = new Panel();
mainPanel.setSize(600,350);
mainPanel.setLayout(new
BorderLayout());
Panel leftPanel = new
Panel(); //ADD
LIST/SCOLLPANE
leftPanel.addMouseListener(this);
list = new
List(13);
list.setFont(new
Font("Courier",Font.PLAIN,12));
list.addMouseListener(this);
listScroll = new ScrollPane
();
listScroll.setSize(250,210);
listScroll.add(list);
leftPanel.add(listScroll);
mainPanel.add(leftPanel,BorderLayout.WEST);
Panel rightPanel = new Panel();
rightPanel.setLayout(new BorderLayout());
rightPanel.addMouseListener(this);
txtFld = new
TextField();
//ADD TEXTFIELD
txtFld.setFont(new
Font("Courier",Font.BOLD, 30));
txtFld.addKeyListener(this);
txtFld.addKeyListener(new
KeyAdapter()
{
public
void keyTyped(KeyEvent ke)
{
txtFld.setCaretPosition(txtFld.getText().length());
char keyChar = ke.getKeyChar();
if(! validKey(keyChar))
{
ke.consume();
}
else
{
actualNumber =
actualNumber + keyChar;
}
}
});
txtFld.addFocusListener(this);
txtFld.addMouseListener(this);
txtFld.hasFocus();
rightPanel.add(txtFld,BorderLayout.NORTH);
radioGrp = new
CheckboxGroup();
//ADD OPTIONBUTTONS
Panel decimals = new
Panel();
decimals.setLayout(new
FlowLayout());
decimals.setBackground(SystemColor.control);
decimals.addMouseListener(this);
for(int i=0; i<
radioBtn.length; i++)
{
radioBtn[i] = new
Checkbox(String.valueOf(i),radioGrp,false);
radioBtn[i].addItemListener(this);
radioBtn[i].addMouseListener(this);
}
radioBtn[2].setState(true);
radioLbl = new Label("Decimals
");
radioLbl.addMouseListener(this);
decimals.add(radioLbl);
for(int i = 0; i <
radioBtn.length; i++)
{
decimals.add(radioBtn[i]);
}
rightPanel.add(decimals,BorderLayout.CENTER);
Panel numPad = new
Panel();
//ADD KEYPAD
numPad.setLayout(new
GridLayout(5,4));
for(int i = 0; i < btn.length;
i++)
{
btn[i] = new
Button();
btn[i].addActionListener(this);
btn[i].setFont(new Font("Serif",Font.BOLD,
18));
if(i<10)
btn[i].setLabel(String.valueOf(i));
else if(i
== 10) btn[i].setLabel("00");
else if(i == 11)
btn[i].setLabel(".");
else if(i == 12)
btn[i].setLabel("x");
else if(i == 13)
btn[i].setLabel("÷");
else if(i == 14)
btn[i].setLabel("-");
else if(i == 15)
btn[i].setLabel("+");
else if(i == 16)
btn[i].setLabel("Cancel");
else if(i == 17)
btn[i].setLabel("Clr All");
else if(i == 18)
btn[i].setLabel("Clr List");
else if(i == 19)
btn[i].setLabel("=");
}
btn[12].setFont(new Font("Serif",Font.PLAIN, 18));
btn[16].setFont(new Font("Serif",Font.BOLD, 11));
btn[17].setFont(new Font("Serif",Font.BOLD, 11));
btn[18].setFont(new Font("Serif",Font.BOLD, 11));
numPad.add(btn[16]);
numPad.add(btn[17]);
numPad.add(btn[18]);
numPad.add(btn[12]);
numPad.add(btn[7]);
numPad.add(btn[8]);
numPad.add(btn[9]);
numPad.add(btn[13]);
numPad.add(btn[4]);
numPad.add(btn[5]);
numPad.add(btn[6]);
numPad.add(btn[14]);
numPad.add(btn[1]);
numPad.add(btn[2]);
numPad.add(btn[3]);
numPad.add(btn[15]);
numPad.add(btn[0]);
numPad.add(btn[10]);
numPad.add(btn[11]);
numPad.add(btn[19]);
rightPanel.add(numPad,BorderLayout.SOUTH);
mainPanel.add(rightPanel,BorderLayout.EAST);
outer.add(mainPanel,BorderLayout.CENTER);
add(outer);
}
}