2010-06-19 56 views
3

在主/詳細視圖中,我有一系列文本字段(以及一個或兩個其他控件),這些字段都與當前所選項目的詳細信息有關。它們全部共享相同的DocumentListener,所以如果您更改其中的任何一個,則會啓用一對「保存」/「丟棄」按鈕。按鈕調用一個方法,我可以愉快地保存/放棄項目。Java AbstractAction有時無法檢測到退出鍵 - 奇怪的行爲

但是,當我使用InputMapActionMap將共享saveAction附加到Enter鍵和共享discardAction到轉義鍵時,discardAction僅適用於某些字段(saveAction適用於它們全部)。

在日誌記錄時,我可以看到,對於首先觸發discardAction的字段,隨後是removeUpdate和insertUpdate的適當組合。

對於不工作的字段,discardAction從不觸發。夠chitter,喋喋不休 - 這裏是相關的代碼(複製和粘貼,不意譯):

docChangeListener = new DocumentListener() { 
    public void insertUpdate(DocumentEvent de) { 
     System.out.println("\t insertUpdate just got triggered"); 
     memberDetailsChanged(de); 
    } 
    public void removeUpdate(DocumentEvent de) { 
     System.out.println("\t removeUpdate just got triggered"); 
     memberDetailsChanged(de); 
    } 
    public void changedUpdate(DocumentEvent de) { 
     // Not a styled document, safely ignore 
    } 
}; 

saveAction = new AbstractAction() { 
    public void actionPerformed(ActionEvent ae) { 
     System.out.println("\t saveAction just got triggered"); 
     saveChanges(); 
    } 
}; 
discardAction = new AbstractAction() { 
    public void actionPerformed(ActionEvent ae) { 
     System.out.println("\t discardAction just got triggered"); 
     discardChanges(); 
    } 
}; 

private void registerDetailField(final JTextField field) { 
    field.getDocument().putProperty("field", field); 
    field.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "saveActionKey"); 
    field.getActionMap().put("saveActionKey", saveAction); 
    field.getInputMap().put(KeyStroke.getKeyStroke("ESCAPE"), "discardActionKey"); 
    field.getActionMap().put("discardActionKey", discardAction); 
    field.getDocument().addDocumentListener(docChangeListener); 
} 

所有的文本字段的登記(使用registerDetailField())相同的方式。他們也有putClientProperty叫他們分配一個類型進行驗證(見下文)。

工作領域和領域之間唯一的區別是實際的驗證過程。我會砍掉它,因爲它太長了,但我覺得我必須包括它。 discardAction SEEMS首先爲可以工作的字段激發,但不工作的字段都有自定義驗證的共同點。

private void verifyField(final JTextField field) { 
    int fieldType = ((Integer)field.getClientProperty("type")).intValue(); 
    String fieldValue = field.getText(); 

    switch (fieldType) { 
     case STANDARD_FIELD: 
      return; // No validation at the moment 
     case MEMBER_NUMBER_FIELD: 
      if (fieldValue.length() == 0) { // Field is required 
       field.setBackground(REQUIRED_COLOUR); 
       field.setToolTipText("This is a required field"); 
       invalidFields.add(field); 
       return; 
      } 
      // Check proposed value is valid 
      if (customTableModel.memberNumStringIsValid(fieldValue, 
            selectedMember.getMemberNumber())) { 
       field.setBackground(NORMAL_COLOUR); 
       field.setToolTipText(null); 
       invalidFields.remove(field); 
      } else { 
       field.setBackground(ERROR_COLOUR); 
       field.setToolTipText("This value must be a unique, 
            positive number"); 
       invalidFields.add(field); 
      } 
      return; 
/* SNIP */ 
     default: 
      return; 
    } 
} 

希望這是我的verifyField方法簡單的問題,我睡眠不足,可俯瞰到付息期但此刻的我完全難倒。

回答

1

您所遇到的問題是與工具提示文本的設置。一旦你這樣做,ToolTipManager正在用它自己的hideTip關鍵筆劃替代inputMap中的放棄操作鍵,也是VK_ESCAE。

0

我建議不要將操作附加到每個文本字段。將它們附加到父容器,並從它檢索輸入映射 - 使用WHEN_ANCESTOR_OF_FOCUSED_COMPONENT條件。

這樣,每當這個容器處於焦點的行動將可

+0

感謝您的諮詢!我之所以沒有這麼做的原因是,在同一個面板中還有其他組件與細節視圖無關。雖然現在寫這個,我意識到將細節視圖組件組合到他們自己的面板中會相當簡單...感謝提示! – Matt 2010-06-20 02:39:37