开发JavaFX动态掩码金额TextField:仿ATM输入模式
实现ATM风格的JavaFX数字输入框
我之前在金融类JavaFX项目里正好做过完全匹配你需求的输入控件——初始默认显示0.00,用户输入数字时从右往左逐位替换,自动维护两位小数的金额格式,比如输入三次9再输入0,会依次显示0.09→0.99→9.99→99.90。下面是完整的可落地实现方案:
核心逻辑思路
- 全程强制保持两位小数的金额格式,不允许用户手动输入小数点或非数字字符
- 把输入的数字当作整数序列处理:当前值去掉小数点转成整数,输入新数字时左移一位(乘以10)加上新数字,再除以100转成两位小数的字符串
- 可配置最大输入金额,避免超出业务允许的范围
完整代码实现
我们可以自定义一个继承自TextField的控件,封装所有输入逻辑:
import javafx.scene.control.TextField; import javafx.scene.input.KeyEvent; public class ATMNumberTextField extends TextField { private static final String DECIMAL_FORMAT = "%.2f"; // 可根据业务需求调整最大允许输入的金额 private static final double MAX_ALLOWED_AMOUNT = 9999.99; public ATMNumberTextField() { super(); // 初始值设置为0.00 setText("0.00"); // 禁止用户直接编辑文本,确保输入逻辑完全由我们控制 setEditable(false); // 监听键盘输入事件 addEventFilter(KeyEvent.KEY_TYPED, this::processDigitInput); addEventFilter(KeyEvent.KEY_PRESSED, this::processBackspace); } private void processDigitInput(KeyEvent event) { char inputChar = event.getCharacter().charAt(0); // 只允许数字输入,过滤其他字符 if (!Character.isDigit(inputChar)) { event.consume(); return; } // 解析当前显示的金额为整数(去掉小数点) String currentText = getText().replace(".", ""); long currentValue = Long.parseLong(currentText); // 计算新值:左移一位加上输入的数字 long newValue = currentValue * 10 + Character.getNumericValue(inputChar); // 转成金额并检查是否超出最大值 double newAmount = newValue / 100.0; if (newAmount > MAX_ALLOWED_AMOUNT) { event.consume(); return; } // 更新显示为两位小数格式 setText(String.format(DECIMAL_FORMAT, newAmount)); } private void processBackspace(KeyEvent event) { // 处理退格键,实现从右往左删除一位 if (event.getCode().equals(javafx.scene.input.KeyCode.BACK_SPACE)) { String currentText = getText().replace(".", ""); if (currentText.length() <= 1) { // 只剩最后一位,重置为初始值0.00 setText("0.00"); } else { // 右移一位(除以10),重新格式化显示 long currentValue = Long.parseLong(currentText); long newValue = currentValue / 10; double newAmount = newValue / 100.0; setText(String.format(DECIMAL_FORMAT, newAmount)); } event.consume(); } } // 对外提供获取当前金额的方法 public double getCurrentAmount() { return Double.parseDouble(getText()); } }
关键代码解释
setEditable(false):禁止用户手动选中或修改文本,避免破坏我们的金额格式,所有输入都通过键盘事件处理KEY_TYPED事件处理:过滤非数字输入,核心逻辑是把当前金额转成整数序列,新输入的数字追加到末尾(相当于左移一位加数字),再转成两位小数格式KEY_PRESSED事件处理:专门处理退格键,实现从右往左删除一位,当只剩最后一位时重置为0.00MAX_ALLOWED_AMOUNT:可根据业务需求调整,比如限制最大输入99999.99
使用示例
在你的JavaFX界面中直接实例化这个控件即可:
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class ATMInputDemo extends Application { @Override public void start(Stage primaryStage) { ATMNumberTextField atmInput = new ATMNumberTextField(); // 可以设置控件的样式,比如调整字体大小、对齐方式 atmInput.setStyle("-fx-font-size: 18px; -fx-alignment: center-right;"); VBox root = new VBox(10, atmInput); root.setStyle("-fx-padding: 20px;"); Scene scene = new Scene(root, 250, 80); primaryStage.setTitle("ATM Style Input"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
测试一下你描述的场景:
- 第一次按9 → 显示
0.09 - 第二次按9 → 显示
0.99 - 第三次按9 → 显示
9.99 - 第四次按0 → 显示
99.90 - 按退格键 → 依次回到
9.99→0.99→0.09→0.00
内容的提问来源于stack exchange,提问作者Samuel Santos
相关产品推荐
相关产品推荐

