用Swing因JDK 8–17默认支持、无需额外配置,组件命名直白、布局简单、单文件可运行;解析算式需过滤非法字符、用双栈法计算、捕获除零异常;按钮事件须清空输入、校验小数点、禁用无谓setEnabled;StringBuffer拼接高效且便于退格与括号校验。

为什么用Swing而不是JavaFX写这个计算器
Swing组件在JDK 8–17中默认可用,无需额外依赖;初学者能直接运行javac + java完成全流程。JavaFX虽然更现代,但JDK 11+已不捆绑,需手动配置javafx.controls模块,容易卡在ClassNotFoundException: javafx.application.Application这类错误上。
- Swing的
JFrame、JButton、JTextField命名直白,事件监听器写法统一(addActionListener) - 布局用
GridLayout(4, 4)就能对齐按钮,不用处理JavaFX的AnchorPane约束或CSS样式 - 所有代码可塞进单个
.java文件,避免初学者被模块划分、包路径、FXML加载等问题干扰
如何安全地解析用户输入的算式字符串
别用ScriptEngineManager执行用户输入——它会执行任意Java代码,比如System.exit(0)或new java.io.File("/").listFiles(),教学项目里极易被忽略这个风险。
- 只允许数字、
+、-、*、/、.、(、)这9种字符,其他一律过滤 - 用双栈法(操作数栈 + 运算符栈)实现简单四则运算,避开
eval()类黑盒调用 - 除零时捕获
ArithmeticException,显示"Error"而非崩溃
public static double calculate(String expr) {
expr = expr.replaceAll("\\s+", ""); // 去空格
if (expr.isEmpty()) return 0;
try {
return new CalculatorEngine().evaluate(expr);
} catch (Exception e) {
return Double.NaN; // 触发后续显示"Error"
}
}
按钮点击事件里最常漏掉的三件事
很多初学者写完button.addActionListener(e -> { ... })就以为结束了,结果遇到界面卡死、按钮重复响应、小数点连按出错等问题。
- 每次计算前清空
inputField.setText(""),否则连续点击=会把上次结果当新输入 - 禁用
button.setEnabled(false)仅在耗时操作中才需要,计算器纯内存运算,**不要加**——反而导致按钮变灰无法再点 - 小数点按钮逻辑必须检查当前输入是否已含小数点:
if (!input.contains(".")) input += ".";,否则1..5这种非法串会传给解析器
为什么建议用StringBuffer而不是String拼接表达式
用户狂点按钮时,表达式字符串频繁修改(如"1+2*" → "1+2*3" → "1+2*3-"),用String每次+=都会新建对象,GC压力大且无必要。
立即学习“Java免费学习笔记(深入)”;
-
StringBuffer线程安全,虽计算器单线程用不到,但它的append()和deleteCharAt()比substring()拼接直观得多 - 退格键实现只需
buffer.deleteCharAt(buffer.length()-1),不用算索引、切片、再拼接 - 最终转
toString()一次即可交给解析器,中间过程无字符串拷贝
复杂点在于括号匹配校验——用户可能输入"((1+2)",这时得遍历StringBuffer统计左右括号数量,不等就拒绝计算。这个细节初学者几乎都会跳过,直到发现"1+((2*3)"也能点等于号并返回错误结果。










