从 JFormattedTextField 中排除零
Exclude zero from JFormattedTextField
我有一个由
创建的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);
}
});
关于此方法的注释:
A JFormattedTextField
有一个 focusLostBehavior
指示在失去焦点时该怎么做。我假设它总是 COMMIT_OR_REVERT
(默认值)。
如果您将 PropertyChangeListener
注册到文本字段,请小心,因为我没有仔细处理触发它的事件。虽然无法解析的输入将 "immediately" 还原(并且不会触发 PropertyChangeEvent
事件),但解析为 0
的值将首先被提交(并触发 PropertyChangeEvent
) 然后才恢复(再次触发 PropertyChangeEvent
)。
关于其他方法的注释:
虽然我认为这是最直接的方法,但几乎可以肯定还有其他方法可以实现这一点,其中涉及扩展和覆盖某些方法。从文本字段本身到为其选择的格式的层次结构可能有点复杂,可以在某些步骤中进行修改,但应注意不要破坏任何内容。
输入验证也可以工作,但它的行为不同——它保持焦点直到输入被验证,而不是允许它丢失和恢复。最终还是程序员的选择。
将类似于 @user1803551 的代码放入 PropertyChangeListener
中效果更好 - 之前,当表单中有默认按钮时点击 "return" 会出现问题 - 它会接收 "action performed" 而无需用户更改输入值。另外,我们不用额外的变量就可以了。
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());
}
});
我有一个由
创建的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);
}
});
关于此方法的注释:
A
JFormattedTextField
有一个focusLostBehavior
指示在失去焦点时该怎么做。我假设它总是COMMIT_OR_REVERT
(默认值)。如果您将
PropertyChangeListener
注册到文本字段,请小心,因为我没有仔细处理触发它的事件。虽然无法解析的输入将 "immediately" 还原(并且不会触发PropertyChangeEvent
事件),但解析为0
的值将首先被提交(并触发PropertyChangeEvent
) 然后才恢复(再次触发PropertyChangeEvent
)。
关于其他方法的注释:
虽然我认为这是最直接的方法,但几乎可以肯定还有其他方法可以实现这一点,其中涉及扩展和覆盖某些方法。从文本字段本身到为其选择的格式的层次结构可能有点复杂,可以在某些步骤中进行修改,但应注意不要破坏任何内容。
输入验证也可以工作,但它的行为不同——它保持焦点直到输入被验证,而不是允许它丢失和恢复。最终还是程序员的选择。
将类似于 @user1803551 的代码放入 PropertyChangeListener
中效果更好 - 之前,当表单中有默认按钮时点击 "return" 会出现问题 - 它会接收 "action performed" 而无需用户更改输入值。另外,我们不用额外的变量就可以了。
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());
}
});