Java 从JFormattedTextField中排除零
我有一个由创建的Java 从JFormattedTextField中排除零,java,swing,jformattedtextfield,Java,Swing,Jformattedtextfield,我有一个由创建的JFormattedTextField JFormattedTextField(NumberFormat.getInstance); 我想增强它的行为,这样如果用户 输入一个零,该字段失去焦点,它的反应与用户输入的完全相同,例如“foo” 使用InputVerifier以某种方式破坏了还原行为,并且使用DecimalFormat的自定义子类在输入零时没有还原,而是清除了字段。 (我所说的零是指解析为BigDecimal.zero)的任何东西) 我使用的代码是: new De
JFormattedTextField
JFormattedTextField(NumberFormat.getInstance);
我想增强它的行为,这样如果用户
输入一个零,该字段失去焦点,它的反应与用户输入的完全相同,例如“foo”
使用InputVerifier
以某种方式破坏了还原行为,并且使用DecimalFormat
的自定义子类在输入零时没有还原,而是清除了字段。(我所说的零是指解析为
BigDecimal.zero
)的任何东西)
我使用的代码是:
new DecimalFormat(){
{
setParseBigDecimal(true);
}
public Number parse(String txt, ParsePosition pos){
BigDecimal num = (BigDecimal) super.parse(txt, pos);
if(num == null || num.compareTo(BigDecimal.ZERO) == 0)
return null;
else return num;
}
当时不接受零,但该字段仅在输入的字母上恢复。您可以添加一个
FocusListener
来执行与内部操作类似的检查:
JFormattedTextField ftf = new JFormattedTextField(NumberFormat.getInstance());
ftf.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
Object lastValid = ftf.getValue();
try {
ftf.commitEdit();
} catch (ParseException e1) {
ftf.setValue(lastValid);
}
Object newValue = ftf.getValue();
if (newValue instanceof Long)
if ((Long) newValue == 0l)
ftf.setValue(lastValid);
}
});
关于这一办法的说明:
有一个JFormattedTextField
,它指示如何处理焦点丢失。我假设它总是focusLostBehavior
(默认值)COMMIT\u或\u REVERT
- 如果在文本字段中注册了
,请小心,因为我没有仔细处理触发它的事件。虽然无法解析的输入将“立即”还原(且不会触发PropertyChangeListener
事件),但解析为PropertyChangeEvent
的值将首先提交(并触发0
),然后才还原(再次触发PropertyChangeEvent
)PropertyChangeEvent
- 虽然我认为这是最直接的方法,但几乎可以肯定还有其他方法可以实现这一点,包括扩展和重写某些方法。从文本字段本身到为其选择的格式的层次结构可能有点复杂,可以在某些步骤中进行修改,但应注意不要破坏任何内容
- 输入验证也可以工作,但它的行为不同——它保持焦点直到输入被验证,而不是允许其丢失和恢复。这最终是程序员的选择
PropertyChangeListener
中效果更好-之前,当表单中有一个默认按钮时,点击“返回”会出现问题-它将收到“已执行的操作”,而用户无需更改输入值。另外,我们没有额外的变量
DecimalFormat format = new DecimalFormat();
format.setParseBigDecimal(true);
JFormattedTextField ftf = new JFormattedTextField(format):
ftf.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("value"))
if ( ((BigDecimal) evt.getNewValue()).compareTo(BigDecimal.ZERO) ==0 )
ftf.setValue(evt.getOldValue());
}
});
“如果用户在字符串中的任何位置输入零”,或者只是
0
?编辑:任何解析为BigDecimal.zero
的内容,谢谢。但我仍然不明白为什么自定义格式不能。我想,这是可以的,只是需要仔细地做。我的方法类似于在洞上贴一块补丁,而不是缝补。