Текст исходника 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); }
}