如何在用户修改前为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,确保组件初始化完成 } }
关键说明
setAllowsInvalid(true):允许文本框显示不符合格式的内容,直到用户完成编辑(比如失去焦点),此时Formatter才会校验输入是否有效,无效则自动回滚到上一个有效值。setText替代setValue:setText直接设置显示内容,不会触发Formatter的解析校验,因此能显示你想要的初始无效字符串。setCommitsOnValidEdit(true):让用户输入的有效内容实时提交到文本框模型,避免丢失输入。- 调整
setVisible时机:把f.setVisible(true)放在所有组件初始化完成后,可避免组件显示异常。
如果必须保持setAllowsInvalid(false),需要自定义NumberFormatter,重写stringToValue和valueToString方法允许初始无效值,但这种方式复杂度较高,基础场景不推荐。
内容的提问来源于stack exchange,提问作者codenoob
相关产品推荐
相关产品推荐

