2013-12-09 1 views
1

다른 양식으로 동일한 정보를 입력하는 2 JFormattedTextField이 있습니다. 사용자가 다른 하나를 변경하면 한 가지 변경 사항을 원합니다. 내가 PropertyChangeListener을 사용하기 전에 이런 식으로 구현했지만, 이번에는 이상한 오류가 발생했습니다.JFrame이 열릴 때이 속성이 이벤트 실행을 변경하는 이유는 무엇입니까?

JFrame이 열리면 PropertyChangeListener 이벤트가 명백한 이유없이 발생합니다. PropertyChangeEventgetNewValue() 값은 null입니다. 내 JFrame의 생성자에서 나중에 그런

private JFormattedTextField fpsField; 

: 여기

내 레이블을 참조하는 모든 코드 당신이 내가 코드와 이벤트의 값을 설정하지 마십시오 볼 수 있듯이

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에 대한 청취자를 작성하지 않았습니다.

답변

3

기본값이 null이므로 null을 적절하게 비교할 수 없으므로 JFrame을 열 때 발생하는 포커스 이벤트는 속성 변경 이벤트를 발생시킵니다. 가능한 해결 방법에 대한 자세한 내용은 아래 코드를 참조하십시오.

하나의 해결 방법 NPE를 제거 할 수는 JFrame가 열릴 때 PropertyChange 이벤트가 발생하지 않습니다 그 일 이후 PropertyChangeListener를 추가하기 전에 fpsField에 기본 값을 설정하는 것입니다. 기본 값을 설정할 수없는 경우

JFormattedTextField fpsField = new JFormattedTextField(NumberFormat.getInstance()); 
fpsField.setValue(0); 

또 다른 해결책은, 이벤트의 이전 및 새 값이 delayField를 업데이트하기 전에 실제로 다른 경우 확인하는 것입니다. 그들은 JFrame이 열릴 때 null입니다.

해고되는 이벤트는 이유 firePCtrue 때문에

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

를 호출 원인이 ACTIVATIONJFormattedTextField에 의해 해고 처리하는 FocusEvent, 때문에, valuePropertyChange 이벤트가 발생합니다. 기본값은 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 인에게 발사합니다.

+0

문서화는 값 집합이 실제 값과 관련이없는'String' 형식으로 어떻게 구성되는지에 관한 것입니다. 짝수 전에 값을 설정하면 예외가 발생하기 때문에 null 값을 확인하기 만하면됩니다. 나는이 문제에 대해 더 많이 묻습니다. 왜냐하면 나는 그 문제를 해결할 수 없기 때문에가 아니라, 무엇이 일어나고 싶어 하는지를 이해하지 못하기 때문입니다. – Fr33dan

+0

마지막으로 이벤트의 전체 체인을 발견했습니다. –

+0

나는 점심에 가서 주제에 대한 에세이로 돌아왔다. 인상적인 작품. – Fr33dan

관련 문제