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

如何在用户修改前为JFormattedTextField设置无效字符串值?

在Java Swing的JFormattedTextField中设置初始无效字符串

需求是在用户自行修改值之前,为JFormattedTextField设置一个无效的初始字符串,但当前代码执行报错。

简化代码

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

public class myGUI{
    private JFrame f;
    private JPanel p;
    private JFormattedTextField ftf;
    private NumberFormat nf;
    private NumberFormatter nfter;

    public myGUI(){
        f = new JFrame("My Window");
        f.setSize(960,450);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        
        p = new JPanel();
        f.add(p);
        p.setLayout(new FlowLayout());
        
        nf = NumberFormat.getInstance();
        nfter = new NumberFormatter(nf);
        nfter.setAllowsInvalid(false);
        
        ftf = new JFormattedTextField(nfter);
        p.add(ftf);
        ftf.setValue("I want this as my ftfs value before it gets changed");
    }
}

报错信息

java.lang.IllegalArgumentException: Cannot format given Object as a Number (in java.text.DecimalFormat)

尝试将nfter.setAllowsInvalid(false)改为true后,报错依旧。

问题原因

你使用的NumberFormatter绑定了NumberFormat,它要求setValue传入的必须是Number类型对象,直接传字符串会触发格式化校验,自然报错。即使打开setAllowsInvalid(true),setValue依然会强制通过Formatter解析值,所以无效。

解决方法

要显示初始无效字符串,不能用setValue,而是直接调用setText设置显示文本,同时调整Formatter的配置允许临时无效输入:

修改后的代码示例

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

public class myGUI{
    private JFrame f;
    private JPanel p;
    private JFormattedTextField ftf;
    private NumberFormat nf;
    private NumberFormatter nfter;

    public myGUI(){
        f = new JFrame("My Window");
        f.setSize(960,450);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        
        p = new JPanel();
        f.add(p);
        p.setLayout(new FlowLayout());
        
        nf = NumberFormat.getInstance();
        nfter = new NumberFormatter(nf);
        // 允许临时显示无效文本,直到用户提交(比如失去焦点)
        nfter.setAllowsInvalid(true);
        // 输入有效时自动提交值到模型
        nfter.setCommitsOnValidEdit(true);
        
        ftf = new JFormattedTextField(nfter);
        p.add(ftf);
        // 用setText直接设置初始显示文本,绕过setValue的Formatter校验
        ftf.setText("I want this as my ftfs value before it gets changed");
        
        f.setVisible(true); // 最后调用setVisible,确保组件初始化完成
    }
}

关键说明

  1. setAllowsInvalid(true):允许文本框显示不符合格式的内容,直到用户完成编辑(比如失去焦点),此时Formatter才会校验输入是否有效,无效则自动回滚到上一个有效值。
  2. setText替代setValue:setText直接设置显示内容,不会触发Formatter的解析校验,因此能显示你想要的初始无效字符串。
  3. setCommitsOnValidEdit(true):让用户输入的有效内容实时提交到文本框模型,避免丢失输入。
  4. 调整setVisible时机:把f.setVisible(true)放在所有组件初始化完成后,可避免组件显示异常。

如果必须保持setAllowsInvalid(false),需要自定义NumberFormatter,重写stringToValue和valueToString方法允许初始无效值,但这种方式复杂度较高,基础场景不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:16:07