Java AbstractAction有时不会检测转义键 - 奇怪的行为

时间:2010-06-19 03:10:12

标签: java swing user-interface action

在主/详细视图中,我有一系列文本字段(以及一个或两个其他控件),这些字段都与当前所选项的详细信息有关。它们共享相同的DocumentListener,因此如果您更改其中任何一个,则会启用一对“保存”/“丢弃”按钮。按钮调用方法,我可以愉快地保存/丢弃项目。

但是,当我使用InputMapActionMap将共享saveAction附加到enter键并将共享discardAction附加到转义键时,discardAction仅适用于某些字段(saveAction适用于所有字段)

登录时我可以看到,对于有效的字段,首先触发discardAction,然后是removeUpdate和insertUpdate的适当组合。

对于不起作用的字段,永远不会触发discardAction。足够的chitter,chatter - 这是相关的代码(复制和粘贴,而不是释义):

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方法的一个简单问题,我因为睡眠不足而忽略了,但此刻我完全被难倒了。

2 个答案:

答案 0 :(得分:1)

您遇到的问题是设置工具提示文字。执行此操作后,ToolTipManager将使用自己的hideTip键击中替换inputMap中的丢弃操作键,也将替换为VK_ESCAE。

答案 1 :(得分:0)

我建议不要对每个文本字段附加操作。将它们附加到父容器并从中检索输入映射时 - 使用WHEN_ANCESTOR_OF_FOCUSED_COMPONENT条件。

这样,只要此容器处于焦点状态,就可以使用