gpt4 book ai didi

java - 为什么在 JFrame 打开时会触发此属性更改事件?

转载 作者:行者123 更新时间:2023-11-29 05:32:59 24 4
gpt4 key购买 nike

我有一个 2 JFormattedTextField s 以不同的形式输入相同的信息。当用户更改另一个时,我想进行一个更改。在使用 PropertyChangeListener 之前我已经实现了类似的东西s,不过我这次遇到了一个奇怪的错误。

当我的JFrame打开 PropertyChangeListener事件无缘无故被解雇。 getNewValue() 的值在 PropertyChangeEvent 上为空。

这是引用我的标签的所有代码:

private JFormattedTextField fpsField;

然后在我的 JFrame 构造函数中:

fpsField = new JFormattedTextField(NumberFormat.getInstance());
fpsField.addPropertyChangeListener("value", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent arg0) {
if(!updatingFPS){
updatingFPS = true;

Float fps = (Float) arg0.getNewValue();

long newDelay = Math.round(1000/fps);
delayField.setValue(newDelay);

updatingFPS = false;
}
}
});
GridBagConstraints gbc_fpsField = new GridBagConstraints();
gbc_fpsField.insets = new Insets(0, 0, 5, 0);
gbc_fpsField.fill = GridBagConstraints.HORIZONTAL;
gbc_fpsField.gridx = 1;
gbc_fpsField.gridy = 0;
monitorPreferencesPane.add(fpsField, gbc_fpsField);
fpsField.setColumns(10);

如您所见,我没有在代码中设置值,而是在我有机会输入任何内容之前调用事件(并生成一个 NullPointerException)。我还没有为 delayField< 编写监听器还没有。

最佳答案

由于默认值为null,打开JFrame时触发的焦点事件将触发属性更改事件,因为null不能充分比较。在可能的解决方案之后,请参阅下面带有代码的完整说明。

消除 NPE 的一个解决方案是在添加 PropertyChangeListener 之前为您的 fpsField 设置一个默认值,因为这样做不会触发 PropertyChange JFrame 打开时的事件。

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) {

由于 firePCtrue,它会在 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);
}

将触发它,oldValuenewValue 都是 null

关于java - 为什么在 JFrame 打开时会触发此属性更改事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20475187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com