You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JFormattedTextField与NumberFormatter、DecimalFormat的异常行为排查

解决方案

要实现输入123456自动转换为1234.5,同时限制数值范围在-9999.9到9999.9之间,需要调整NumberFormatter的配置并自定义解析逻辑,以下是修正后的代码:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.text.*;

public class testwindow extends JPanel {
    private JFormattedTextField field1;

    public testwindow() {
        try {
            DecimalFormat decimalFormat = new DecimalFormat("#0.0;-#0.0");
            decimalFormat.setMinimumIntegerDigits(1);
            decimalFormat.setMaximumIntegerDigits(4);
            decimalFormat.setMinimumFractionDigits(1);
            decimalFormat.setMaximumFractionDigits(1);

            // 自定义NumberFormatter,处理输入过长的情况
            NumberFormatter realFormatter = new NumberFormatter(decimalFormat) {
                @Override
                public Object parseObject(String text) throws ParseException {
                    // 移除负号,单独处理数字部分
                    String numText = text.replace("-", "");
                    if (numText.length() > 5) { // 4位整数+1位小数,共5位有效长度
                        // 截取前4位作为整数部分,第5位作为小数部分
                        String integerPart = numText.substring(0, 4);
                        String fractionPart = numText.substring(4, 5);
                        numText = integerPart + "." + fractionPart;
                        // 还原负号
                        if (text.startsWith("-")) {
                            numText = "-" + numText;
                        }
                    }
                    // 解析处理后的字符串
                    Number num = (Number) super.parseObject(numText);
                    // 强制数值在设定范围内
                    double value = num.doubleValue();
                    if (value > 9999.9) {
                        return 9999.9;
                    } else if (value < -9999.9) {
                        return -9999.9;
                    }
                    return num;
                }
            };

            realFormatter.setOverwriteMode(true);
            realFormatter.setAllowsInvalid(false);
            // 设置数值上下限,防止解析后超出范围
            realFormatter.setMinimum(-9999.9);
            realFormatter.setMaximum(9999.9);
            // 使用Double类型避免float精度丢失问题
            realFormatter.setValueClass(Double.class);

            field1 = new JFormattedTextField(realFormatter);
            field1.setValue(0.0);

            setPreferredSize(new Dimension(215, 30));
            setLayout(new GridLayout(1, 1));
            add(field1);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("MyPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new testwindow());
        frame.pack();
        frame.setVisible(true);
    }
}

关键调整说明

  • 自定义解析逻辑:重写parseObject方法,当输入数字长度超过5位时,自动拆分整数和小数部分,确保输入123456转换为1234.5。
  • 数值范围限制:通过setMinimum和setMaximum强制最终值在-9999.9到9999.9区间内,避免超出范围的异常数值。
  • 替换数值类型:用Double替代原有的Float,解决浮点数精度丢失导致的异常显示(如之前的4050.6问题)。
  • 保留覆盖模式:保持setOverwriteMode(true),确保输入时逐位覆盖现有内容,符合预期的输入体验。

解决的原问题

  1. 输入123456时自动转换为1234.5,而非异常数值。
  2. 修复了仅绑定DecimalFormat时负号只能在首位输入的问题,通过NumberFormatter统一处理正负号。
  3. 解决了多次输入9仅增加0.1的问题,自定义解析确保输入的数字正确整合到数值中。

内容的提问来源于stack exchange,提问作者kcswalter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:45:20