採用 GridBagLayout 精確佈局,按鈕事件分離為數字輸入與運算命令兩類監聽器。
public class SwingCalculator extends JFrame {
private JTextField display;
private double result = 0;
private String lastOp = "=";
private boolean start = true;
public SwingCalculator() {
setTitle("計算器"); setDefaultCloseOperation(EXIT_ON_CLOSE);
display = new JTextField(20); display.setHorizontalAlignment(JTextField.RIGHT);
// 佈局代碼省略... 關鍵邏輯如下:
}
private class NumberAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
String input = e.getActionCommand();
if (start) { display.setText(""); start = false; }
if (!input.equals("←")) display.setText(display.getText() + input);
else { /* 退格邏輯 */ }
}
}
private class OperatorAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
String op = e.getActionCommand();
if (!start) calculate(Double.parseDouble(display.getText()));
lastOp = op; start = true;
}
}
private void calculate(double x) {
switch (lastOp) {
case "+": result += x; break;
case "-": result -= x; break;
case "*": result *= x; break;
case "/": result = (x != 0) ? result / x : 0; break;
case "=": result = x; break;
}
display.setText(String.valueOf(result));
}
}
使用 Frame、Panel、GridLayout,成員內部類實現監聽器,邏輯與 Swing 版本相似但組件更輕量。
public class ConsoleCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("1.加 2.減 3.乘 4.除 0.退出");
int op = sc.nextInt(); if (op == 0) break;
System.out.print("運算元1: "); double a = sc.nextDouble();
System.out.print("運算元2: "); double b = sc.nextDouble();
double r = switch (op) {
case 1 -> a + b; case 2 -> a - b;
case 3 -> a * b; case 4 -> b != 0 ? a / b : Double.NaN;
default -> Double.NaN;
};
System.out.printf("結果: %.2f%n%n", r);
}
}
}
// 命令介面
interface Command { double execute(double a, double b); }
// 具體命令
class AddCmd implements Command { public double execute(double a, double b) { return a + b; } }
class SubCmd implements Command { public double execute(double a, double b) { return a - b; } }
class MulCmd implements Command { public double execute(double a, double b) { return a * b; } }
class DivCmd implements Command { public double execute(double a, double b) { return b != 0 ? a / b : Double.NaN; } }
// 工廠
class CommandFactory {
private static final Map MAP = Map.of(
"+", new AddCmd(), "-", new SubCmd(),
"*", new MulCmd(), "/", new DivCmd()
);
public static Command get(String op) { return MAP.get(op); }
}
// 使用
public class CommandCalculator {
private double memory = 0;
public double compute(double a, String op, double b) {
Command cmd = CommandFactory.get(op);
if (cmd == null) throw new IllegalArgumentException("未知運算符: " + op);
memory = cmd.execute(a, b);
return memory;
}
}
| 模式 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| Swing GUI | 桌面應用 | 原生跨平台、功能豐富 | 代碼冗長、界面風格較舊 |
| AWT | 教學/極簡工具 | 無依賴、啟動快 | 外觀原生、功能受限 |
| 控制台 | 腳本/測試/服務端 | 零依賴、易自動化 | 無圖形界面 |
| 命令模式 | 科學計算器/規則引擎 | 開閉原則、易擴展運算符 | 初期結構較複雜 |
exp4j 或 Javaluator 支援括號、函數、優先級InputMap/ActionMap 綁定數字鍵、Enter、Esc