Текст исходника SCalc.java (все внесенные изменения выделены):
/** * class StackCalc * Stack Calculator of Real Numbers * * <applet code="SCalc.class" width=380 height=450> * </applet> * * The applet nees JDK 1.1. * Tested in RedHat Linux 4.2 (JDK 1.1.3 and 1.1.5) and * under Win95, JDK 1.1.5. * */
// //------------------------------------------------------ This is the first programm for the examination. It is made by VILenin (with the help of Arty & Cherry & RAF). //------------------------------------------------------ //
import java.awt.*; import java.awt.event.*; import java.applet.Applet;
public class SCalc extends Applet { DoubleStack stack; double number; boolean numberSet = false;
Button plusButton; Button minusButton; Button multButton; Button divButton;
Button sqrtButton; Button sinButton; Button cosButton; Button expButton; Button piButton; Button eButton;
Button pushButton; Button popButton; Button initButton;
// //--------------------------------------------------------- Button nodButton; Button powButton; Button powMButton; //--------------------------------------------------------- //
TextField inputNumber; TextField resultNumber;
// Layout constants static final int leftMargin = 5; static final int topMargin = 5; static final int headSkip = 30; static final int vertSkip = 5; static final int horSkip = 5; static final int buttonWidth = 60; static final int buttonHeight = 30; static final int stackDy = 24; static final int numberWidth = 300;
public static void main(String[] args) { Frame f = new Frame("Stack Calculator of Real Numbers");
WindowAdapter wa = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; f.addWindowListener(wa);
f.setFont(new Font("Helvetica", Font.PLAIN, 14));
// Add menu bar final MenuBar mb = new MenuBar(); f.setMenuBar(mb); final Menu fileMenu = new Menu("File"); final MenuItem quitItem = new MenuItem("Quit"); fileMenu.add(quitItem); mb.add(fileMenu);
ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { // System.out.println("Action " + e); if (e.getActionCommand().equals("Quit")) { System.exit(0); } } }; fileMenu.addActionListener(al);
SCalc sc = new SCalc(); f.add("Center", sc);
// f.pack(); f.setSize( 2*leftMargin + buttonWidth + horSkip + numberWidth + 10, 2*topMargin + 11 * (buttonHeight + vertSkip) + headSkip + vertSkip + 60 // For menu bar ); f.setLocation(20, 40); sc.init(); sc.start();
f.setVisible(true); }
public SCalc() { stack = new DoubleStack(); }
public void init() { setLayout(null);
setFont(new Font("Helvetica", Font.PLAIN, 14)); setBackground(Color.lightGray);
Label headline = new Label("Stack Calculator of Real Numbers"); headline.setFont(new Font("TimesRoman", Font.BOLD, 18)); add(headline); headline.setBounds(leftMargin, topMargin, 300, 30);
plusButton = new Button("+"); minusButton = new Button("-"); multButton = new Button("*"); divButton = new Button("/");
sqrtButton = new Button("sqrt"); expButton = new Button("exp"); sinButton = new Button("sin"); cosButton = new Button("cos"); piButton = new Button("pi"); eButton = new Button("e");
// //------------------------------------------------------- nodButton = new Button("nod"); powButton = new Button("pow"); powMButton = new Button("pow mod m"); //------------------------------------------------------- //
pushButton = new Button("Push"); popButton = new Button("Delete stack top"); initButton = new Button("Initialize");
// Button colors plusButton.setForeground(Color.blue); minusButton.setForeground(Color.blue); multButton.setForeground(Color.blue); divButton.setForeground(Color.blue);
sqrtButton.setForeground(Color.blue); expButton.setForeground(Color.blue); sinButton.setForeground(Color.blue); cosButton.setForeground(Color.blue); piButton.setForeground(Color.blue); eButton.setForeground(Color.blue);
// //------------------------------------------------------ nodButton.setForeground(Color.green); powButton.setForeground(Color.green); powMButton.setForeground(Color.green); //------------------------------------------------------ //
resultNumber = new TextField(); resultNumber.setEditable(false); resultNumber.setForeground(Color.blue); add(resultNumber);
inputNumber = new TextField(); add(inputNumber);
// Add buttons to applet add(plusButton); add(minusButton); add(multButton); add(divButton);
add(sqrtButton); add(expButton); add(sinButton); add(cosButton); add(piButton); add(eButton);
// //------------------------------------------------------- add(nodButton); add(powButton); add(powMButton); //------------------------------------------------------- //
add(pushButton); add(popButton); add(initButton);
// Set component shapes int x0 = leftMargin; int x1 = leftMargin + buttonWidth + horSkip; int y = topMargin + headSkip + vertSkip; // Skip headline int dy = buttonHeight + vertSkip;
Label resultLabel = new Label("Result:"); add(resultLabel); resultLabel.setBounds(x0, y, buttonWidth, buttonHeight); resultNumber.setBounds(x1, y, numberWidth, buttonHeight); y += dy;
Label inputLabel = new Label("Input:"); add(inputLabel); inputLabel.setBounds(x0, y, buttonWidth, buttonHeight); inputNumber.setBounds(x1, y, numberWidth - buttonWidth - horSkip, buttonHeight); pushButton.setBounds(x1 + numberWidth - buttonWidth, y, buttonWidth, buttonHeight); y += dy;
plusButton.setBounds(x0, y, buttonWidth, buttonHeight); minusButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
multButton.setBounds(x0, y, buttonWidth, buttonHeight); divButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
sqrtButton.setBounds(x0, y, buttonWidth, buttonHeight); expButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
sinButton.setBounds(x0, y, buttonWidth, buttonHeight); cosButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
piButton.setBounds(x0, y, buttonWidth, buttonHeight); eButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
// //----------------------------------------------------- nodButton.setBounds(x0, y, buttonWidth, buttonHeight); powButton.setBounds(x1, y, buttonWidth, buttonHeight); y += dy;
powMButton.setBounds(x0, y, 2*buttonWidth+horSkip, buttonHeight); y += dy; //----------------------------------------------------- //
popButton.setBounds(x0, y, 2*buttonWidth+horSkip, buttonHeight); y += dy;
initButton.setBounds(x0, y, 2*buttonWidth+horSkip, buttonHeight); y += dy;
// Add action listener for "Input" text field // (for processing the "Enter" button) inputNumber.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // System.out.println("Text action " + e); onPush(); } } );
// Add action listener for buttons SCalcListener bl = new SCalcListener();
plusButton.addActionListener(bl); minusButton.addActionListener(bl); multButton.addActionListener(bl); divButton.addActionListener(bl);
sqrtButton.addActionListener(bl); expButton.addActionListener(bl); sinButton.addActionListener(bl); cosButton.addActionListener(bl); piButton.addActionListener(bl); eButton.addActionListener(bl);
// //--------------------------------------------------------- nodButton.addActionListener(bl); powButton.addActionListener(bl); powMButton.addActionListener(bl); //--------------------------------------------------------- //
pushButton.addActionListener(bl); popButton.addActionListener(bl); initButton.addActionListener(bl);
inputNumber.requestFocus(); // Set focus to input number field }
public void paint(Graphics g) { int x = leftMargin + 2 * (buttonWidth + horSkip); int y = topMargin + headSkip + vertSkip + // Skip headline 2 * (buttonHeight + vertSkip); // Skip result & input fields
int stackTop = y + buttonHeight + vertSkip; int stackLeft = x; int stackWidth = 0; int stackHeight = vertSkip;
g.setColor(Color.red); g.drawString("Stack: Depth = " + stack.depth(), x, y + 18);
FontMetrics fm = g.getFontMetrics();
for (int i = 0; i < stack.depth(); i++) { String s = "" + stack.elementAt(i); // Convert number to string g.drawString( s, stackLeft + horSkip, stackTop + stackDy*i + 20 ); int w = fm.stringWidth(s); if (w > stackWidth) stackWidth = w; }
stackWidth += 2*horSkip;
if (stack.depth() > 0) { stackHeight = stack.depth()*stackDy; } else { stackTop += vertSkip; }
if (stackWidth < 40) stackWidth = 40;
g.drawLine( stackLeft, stackTop, stackLeft, stackTop + stackHeight ); g.drawLine( stackLeft, stackTop + stackHeight, stackLeft + stackWidth, stackTop + stackHeight ); g.drawLine( stackLeft + stackWidth, stackTop + stackHeight, stackLeft + stackWidth, stackTop ); }
public void start() {
}
// Action listeners class SCalcListener implements ActionListener { public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == plusButton) onPlus(); else if (source == minusButton) onMinus(); else if (source == multButton) onMult(); else if (source == divButton) onDiv(); else if (source == sqrtButton) onSqrt(); else if (source == expButton) onExp(); else if (source == sinButton) onSin(); else if (source == cosButton) onCos(); else if (source == piButton) onPi(); else if (source == eButton) onE();
// //--------------------------------------------------- else if (source == nodButton) onNod(); else if (source == powButton) onPow(); else if (source == powMButton) onPowM(); //--------------------------------------------------- //
else if (source == pushButton) onPush(); else if (source == popButton) onPop(); else if (source == initButton) onInit();
inputNumber.requestFocus(); } }
void onPlus() { if (stack.depth() < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; } double x2 = stack.pop(); double x1 = stack.pop(); double res = x1 + x2; stack.push(res); showResult(); }
void onMinus() { if (stack.depth() < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; } double x2 = stack.pop(); double x1 = stack.pop(); double res = x1 - x2; stack.push(res); showResult(); }
void onMult() { if (stack.depth() < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; } double x2 = stack.pop(); double x1 = stack.pop(); double res = x1 * x2; stack.push(res); showResult(); }
void onDiv() { if (stack.depth() < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; } double x2 = stack.top(); if (x2 == 0.) { System.out.println("Zero division"); showMessage("Zero division"); return; } stack.pop(); double x1 = stack.pop(); double res = x1 / x2; stack.push(res); showResult(); }
void onSqrt() { if (stack.empty()) { showMessage("Cannot perform operation: Stack empty"); return; } double x = stack.top(); if (x < 0.) { System.out.println("Square root of negative number"); showMessage("Square root of negative number"); return; } stack.pop(); double res = Math.sqrt(x); stack.push(res); showResult(); }
void onExp() { if (stack.empty()) { showMessage("Cannot perform operation: Stack empty"); return; } double x = stack.pop(); double res = Math.exp(x); stack.push(res); showResult(); }
void onSin() { if (stack.empty()) { showMessage("Cannot perform operation: Stack empty"); return; } double x = stack.pop(); double res = Math.sin(x); stack.push(res); showResult(); }
void onCos() { if (stack.empty()) { showMessage("Cannot perform operation: Stack empty"); return; } double x = stack.top(); stack.pop(); double res = Math.cos(x); stack.push(res); showResult(); }
void onPi() { stack.push(Math.PI); showResult(); }
void onE() { stack.push(Math.E); showResult(); }
// //------------------------------------------------------------ void onNod() { //Euclid Algorithm if (stack.depth < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; }
int x1 = (int) stack.pop(); x1 = Math.abs(x1); int x2 = (int) stack.pop(); x2 = Math.abs(x2); int r = 1; //Remainder
while (r > 0) { r = x1 % x2; x1 = x2; x2 = r; }
stack.push(x1); showResult(); }
void onPow() { if (stack.depth < 2) { showMessage("Cannot perform operation: Stack depth < 2"); return; }
int x2 = (int) stack.pop(); x2 = Math.abs(x2); int x1 = (int) stack.pop(); x1 = Math.abs(x1); int i = x1; int u = x2; int v = 1;
while (u > 0) { if (u % 2 == 0) { i *= i; u /= 2; } else { u--; v *= i; } }
stack.push(v); showResult(); }
void onPowM() { if (stack.depth < 3) { showMessage("Cannot perform operation: Stack depth < 3"); return; }
int m = (int) stack.pop(); m = Math.abs(m); int x2 = (int) stack.pop(); x2 = Math.abs(x2); int x1 = (int) stack.pop(); x1 = Math.abs(x1); int i = x1; int u = x2; int v = 1;
while (u > 0) { if (u % 2 == 0) { i *= i; i = i % m; u /= 2; } else { u--; v *= i; v = v % m; } }
stack.push(v); showResult(); } //------------------------------------------------------------ //
void onPush() { input(); if (numberSet) { stack.push(number); inputNumber.setText(""); numberSet = false; number = 0.; showResult(); } }
void onPop() { if (stack.depth() > 0) { stack.pop(); showResult(); } }
void onInit() { stack.init(); number = 0.; numberSet = false;
inputNumber.setText(""); resultNumber.setText("");
repaint(); }
void input() { number = 0.; String text = inputNumber.getText(); if (text.equals("")) { numberSet = false; return; }
number = Double.valueOf(text).doubleValue(); numberSet = true; }
void showResult() { if (stack.depth() > 0) { resultNumber.setText("" + stack.top()); } else { resultNumber.setText(""); } repaint(); }
void showMessage(String m) { resultNumber.setText(m); repaint(); } }
// Stack of real numbers class DoubleStack { final int MAX_DEPTH = 1024; double stack[] = new double[MAX_DEPTH]; int depth = 0;
public DoubleStack() { init(); }
public void init() { depth = 0; }
int depth() { return depth; }
boolean empty() { return (depth == 0); }
double pop() throws StackException { if (depth <= 0) { throw new StackException("Stack is empty"); } else { double ret = stack[depth - 1]; depth--; return ret; } }
double top() throws StackException { if (depth <= 0) { throw new StackException("Stack is empty"); } else { return stack[depth - 1]; } }
void push(double x) throws StackException { if (depth >= MAX_DEPTH) { throw new StackException("Stack overflow"); } else { stack[depth] = x; depth++; } }
// Return the element at the depth i (zero is a top of stack) double elementAt(int i) { if (i >= depth) throw new StackException("Stack depth is too small"); else return stack[depth - 1 - i]; } }
class StackException extends RuntimeException { public StackException() {} public StackException(String reason) { super(reason); } }