在主/詳細視圖中,我有一系列文本字段(以及一個或兩個其他控件),這些字段都與當前所選項目的詳細信息有關。它們全部共享相同的DocumentListener
,所以如果您更改其中的任何一個,則會啓用一對「保存」/「丟棄」按鈕。按鈕調用一個方法,我可以愉快地保存/放棄項目。Java AbstractAction有時無法檢測到退出鍵 - 奇怪的行爲
但是,當我使用InputMap
和ActionMap
將共享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方法簡單的問題,我睡眠不足,可俯瞰到付息期但此刻的我完全難倒。
感謝您的諮詢!我之所以沒有這麼做的原因是,在同一個面板中還有其他組件與細節視圖無關。雖然現在寫這個,我意識到將細節視圖組件組合到他們自己的面板中會相當簡單...感謝提示! – Matt 2010-06-20 02:39:37