由于缺省值为null
,打开JFrame
时激发的焦点事件将触发属性更改事件,因为无法充分比较null
。可能的解决方案之后,请参阅下面代码的完整说明。
一个解决方案摆脱了NPE的是加入PropertyChangeListener
因为这样做的JFrame
打开时将不发射PropertyChange
事件之前设置的默认值您fpsField
。
JFormattedTextField fpsField = new JFormattedTextField(NumberFormat.getInstance());
fpsField.setValue(0);
另一种解决办法,如果你不能设置默认值,是检查是否在事件新旧值更新delayField
之前实际上是不同的。当JFrame
开放时,它们都是null
。
原因是触发事件是因为FocusEvent
,其中的原因是ACTIVATION
由您JFormattedTextField
发射和处理,这就要求
/**
* Processes any focus events, such as
* <code>FocusEvent.FOCUS_GAINED</code> or
* <code>FocusEvent.FOCUS_LOST</code>.
*
* @param e the <code>FocusEvent</code>
* @see FocusEvent
*/
protected void processFocusEvent(FocusEvent e) {
super.processFocusEvent(e);
// ignore temporary focus event
if (e.isTemporary()) {
return;
}
if (isEdited() && e.getID() == FocusEvent.FOCUS_LOST) {
InputContext ic = getInputContext();
if (focusLostHandler == null) {
focusLostHandler = new FocusLostHandler();
}
// if there is a composed text, process it first
if ((ic != null) && composedTextExists) {
ic.endComposition();
EventQueue.invokeLater(focusLostHandler);
} else {
focusLostHandler.run();
}
}
else if (!isEdited()) {
// reformat
setValue(getValue(), true, true);
}
}
和
/**
* Does the setting of the value. If <code>createFormat</code> is true,
* this will also obtain a new <code>AbstractFormatter</code> from the
* current factory. The property change event will be fired if
* <code>firePC</code> is true.
*/
private void setValue(Object value, boolean createFormat, boolean firePC) {
因为firePC
是true
,它会在value
上触发PropertyChange
事件。
最后,由于默认值是null
,病情居然触发事件
/**
* Support for reporting bound property changes for Object properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
*/
protected void firePropertyChange(String propertyName,
Object oldValue, Object newValue) {
PropertyChangeSupport changeSupport;
synchronized (getObjectLock()) {
changeSupport = this.changeSupport;
}
if (changeSupport == null ||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
return;
}
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
将触发它,oldValue
和newValue
既是null
。
我认为文档是关于如何将值集格式化为一个'字符串'并且与实际值无关。在even之前设置该值可能会解决异常,我也可以简单地检查一个空值。我更多地问这个问题并不是因为我无法解决这个问题,而是因为我不明白发生了什么,想要什么。 – Fr33dan
终于找到了整个事件链。 –
我去吃午饭,回到关于这个问题的文章。令人赞叹的工作。 – Fr33dan