Java Swing计算器需用ScriptEngine解析表达式并用BigDecimal格式化结果,避免浮点误差;键盘响应应通过InputMap+ActionMap实现,确保全局快捷键稳定可用。

用Swing写个能点按钮算加减乘除的GUI计算器
Java自带的Swing足够做出一个可运行的桌面计算器,不需要额外依赖。核心是把数字按钮、运算符按钮和等号按钮的点击事件,映射到字符串拼接和表达式计算逻辑上。
常见错误是直接用Double.parseDouble()硬转整个表达式(比如"12+3*4"),这会抛NumberFormatException——Java不会自动解析算术字符串。
- 用
JFrame做主窗口,JTextField显示输入和结果(设为setEditable(false)防误输) - 每个数字按钮绑定
ActionListener,追加数字字符到显示框文本末尾 - 运算符按钮(+、−、×、÷)需先记录上一个操作数和当前运算符,清空显示框准备输下一个数
-
Equals按钮触发实际计算:用ScriptEngine(javax.script)最省事,或手写简易双栈计算器(处理优先级)
用ScriptEngine安全执行用户输入的算术表达式
别自己写eval——Java没内置eval,但ScriptEngineManager可调用JavaScript引擎,对纯数字表达式较安全(禁用函数调用后风险可控)。
注意JDK 15+默认移除了nashorn引擎,若用较新JDK,需显式添加graalvm-js依赖,或降级用javax.script + ScriptEngineManager().getEngineByName("js")在JDK 11–14中跑通。
立即学习“Java免费学习笔记(深入)”;
- 初始化:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); - 执行:
Object result = engine.eval("12 + 3 * 4");→ 返回Double类型结果 - 务必用
try-catch捕获ScriptException(如输入"1++2"或"alert()") - 生产环境禁用
eval类操作;教学/本地工具可接受
避免浮点误差导致显示异常(比如0.1 + 0.2 = 0.30000000000000004)
计算器显示必须“看起来正确”。double本身精度没问题,但二进制浮点表示会导致输出冗余小数位。
不能简单用Math.round(x * 100) / 100.0——这会误伤大数(如123456789.123);也不该无脑String.format("%.10g", x),它可能科学计数。
- 推荐用
BigDecimal做最终结果格式化:new BigDecimal(Double.toString(x)).stripTrailingZeros().toPlainString() - 注意
Double.toString(x)比String.valueOf(x)更可靠,能避免0.0变成0.000000 - 如果全程用
BigDecimal做运算(需把输入字符串转为BigDecimal),可彻底规避浮点问题,但代码量翻倍
监听键盘输入并响应数字键和回车
光靠鼠标点按钮不够直观。让JTextField或整个JFrame响应键盘事件,提升可用性。
别用KeyListener直接绑在JTextField上——焦点丢失就失效;改用InputMap + ActionMap做全局快捷键映射,稳定且不抢焦点。
- 绑定数字键:
inputMap.put(KeyStroke.getKeyStroke("0"), "digit0"); - 绑定运算符:
inputMap.put(KeyStroke.getKeyStroke("+"), "op_add");(注意加号需转义或用"typed +") - 回车触发计算:
inputMap.put(KeyStroke.getKeyStroke("ENTER"), "equals"); - 所有Action需注册到
ActionMap,并在Action实现里调用对应逻辑方法
键盘事件容易忽略Shift状态(比如按Shift+8得*而非(),测试时记得切英文输入法,中文输入法下KeyStroke可能不触发。










