失去焦点时,可编辑的JComboBox触发ActionListener

时间:2016-12-12 15:14:05

标签: java combobox actionlistener

我正在编写一个扩展JComboBox的类(UIPromptComboBox)。组合框是可编辑的,对于该类的一个应用程序,它使用控件ActionListener实现。

目前,当编辑组合框时,它会激活ActionListener,这是好的。然而,当取消选择组合框时,ActionListener也会被触发,我无法区分这两个事件,也不想在取消选择组合框时触发它。

实施班级

private void addUIField() {
        // Initialise and place combobox
        this.myGuiTextField = new UIPromptComboBox();
        myGuiTextField.setSize(COMBO_WIDTH, defaultHeight);
        GuiUtils.positionControl(myPanel, myGuiTextField, myTop, PROMPT_X_LOC);

        //Add action listener
        myGuiTextField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                if (evt.getActionCommand().equals("comboBoxEdited")) {
                    newUIcreated((UIPromptComboBox) evt.getSource());
                }
            }

            private void newUIcreated(UIPromptComboBox alteredGuiTextField) {
                try {
                    UIPrompt uip = alteredGuiTextField.getUIPrompt(((PowerPointTextItem) myPPTRef).getValue());
                    if (!simInfo.isInPrompts(uip)) {
                        simInfo.addUIPrompt(uip);
                        alteredGuiTextField.addNewUIPrompt(uip);
                    }
                } catch (MissingPowerpointItem ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
        });
    }

扩展JComboBox的类

public class UIPromptComboBox extends JComboBox {

    public UIPromptComboBox(UIPrompt[] items) {
        super(items);
        this.setEditable(true);
    }

    public UIPromptComboBox() {
        this.setEditable(true);
        this.setEnabled(false);
    }

    /**
     * returns either the selected UI prompt or a new prompt using the example
     * text
     *
     * @param exampleText only used if new prompt is created
     * @return UI prompt selected
     */
    public UIPrompt getUIPrompt(String exampleText) {
        UIPrompt uIPrompt = null;
        Object returnedItem = this.getSelectedItem();
        if (returnedItem instanceof UIPrompt) {
            uIPrompt = (UIPrompt) returnedItem;
        } else if (returnedItem instanceof String) {
            uIPrompt = new UIPrompt((String) returnedItem, exampleText);
        }
        return uIPrompt;
    }

    public void addNewUIPrompt(UIPrompt newPrompt) {
        ActionListener[] actionListerners = this.getActionListeners();

        this.removeActionListener(this);
        this.addItem(newPrompt);
        this.setSelectedItem(newPrompt);

        for (ActionListener al : actionListerners) {
            this.addActionListener(al);
        }

    }

    /**
     * Used for displaying a report value sentence
     * i.e. a string that is not associated with UI Prompts
     * @param newText report value sentence
     */
    public void setText(String newText) {
        this.removeAllItems();
        this.addItem(newText);
        this.setSelectedItem(newText);
    }

    /**
     * For when the UI prompts can be added on construction
     *
     * @param currentUIs list of UI promts
     */
    public void addItems(UIPrompt[] currentUIs) {
        this.removeAllItems();
        DefaultComboBoxModel boxModel = new DefaultComboBoxModel(currentUIs);
        this.setModel(boxModel);
    }

}

由于失去焦点而导致的多次射击导致多个对象被创建并添加到列表中。我想我可能错误地实现了ActionListener。谢谢你的帮助

2 个答案:

答案 0 :(得分:0)

正如您所说,如果用户按下回车,您只希望触发事件。实现它的更好方法是使用keylistener而不是动作监听器。

myGuiTextField.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            newUIcreated((UIPromptComboBox) evt.getSource());
        }
    }

    private void newUIcreated(UIPromptComboBox alteredGuiTextField) {
           try {
                UIPrompt uip = alteredGuiTextField.getUIPrompt(((PowerPointTextItem) myPPTRef).getValue());
            if (!simInfo.isInPrompts(uip)) {
                simInfo.addUIPrompt(uip);
                alteredGuiTextField.addNewUIPrompt(uip);
            }
        } catch (MissingPowerpointItem ex) {
            Exceptions.printStackTrace(ex);
        }
    }
});

现在,只有当用户按下Enter键时才会触发您的事件newUIcreated,而不是其他时间。用这个

替换你的动作监听器

答案 1 :(得分:0)

我现在终于找到了这个问题。

显示UIPrompt包括添加一个有时包含换行符号的字符串。

单击另一个字段的操作触发了UIPrompt的渲染,但是当它包含换行符时,它再次触发ActionListener。这就是comboBoxEdited重复动作的原因。