Java:需要按Enter键才能触发action和actionlistener

时间:2015-06-08 19:11:52

标签: java swing action actionlistener

好的,所以我一直在改变我的这个练习程序,我仍然坚持同样的问题。希望得到一些帮助。

注意:我正在尽我所能,使用基本代码段和简单缩写来描述我程序的各种元素。首先是基本描述,代码段将根据需要显示。

问题。在我的GUI中,我有三个主要类。我的窗口,面板A和面板B.在面板B中,我有一个搜索字段,根据是否需要显示或消失。有三个按钮:查找(显示搜索字段),搜索(运行搜索,隐藏字段)和取消(只是再次隐藏字段)。另外,我正在使用输入/动作映射键绑定,以便按下ENTER时我的搜索文本字段将复制搜索按钮行为,并且在ESCAPE上将复制取消按钮行为。

总之,这些组件执行两个关键行为:

1)显示或隐藏搜索字段

2)启动一个SwingWorker,它在后台运行搜索,并在完成后更新GUI。

最初,我有一个旨在完成所有这一切的动作,并且它的效果非常好。然而,随着我的进展,我意识到在运行搜索后,偶尔会出现一些情况,我希望更新面板A中显示的数据以匹配要显示的内容。这种情况不会经常发生,但它偶尔会产生我想要阻止的不协调。

我的行动当时是Panel B中的一个内部类。但是,对于SwingWorker来说,影响A和A组。 B,我需要将它们作为参数传递给SwingWorker的构造函数,如下所示:

public SampleSwingWorker(String text, JPanel panelA, JPanel panelB){
        this.text = text;
        this.panelA = panelA;
        this.panelB = panelB;
    }

作为Panel B中的Inner类,我不能将Panel A作为参数传递。

然后,我接着尝试了很多关于如何设置这些操作的新配置。最终我开始意识到唯一的问题是SwingWorker。它是代码中唯一需要访问Panel A& A的部分。小组B。

所以我重组了整个设置。在上面,我列出了两种行为。我的行动现在只影响行为1),无论是否显示或隐藏搜索字段。同时,我在Window类中创建了一个ActionListener,并通过其构造函数将其传递给Panel B.结果是看起来像这样的代码。 ActionListener处理行为2)。结果代码如下所示:

public class SampleWindow {

    private PanelA panelA;
    private PanelB panelB;

    private JPanel createContentPane(){
        JPanel contentPane = new JPanel(new MigLayout());

        panelA = new PanelA();
        contentPane.add(panelA, "dock left");

        panelB = new PanelB(new SampleActionListener());
        contentPane.add(panelB, "dock center");

        return contentPane;
    }

    private class SampleActionListener implements ActionListener{

        public void actionPerformed(ActionEvent ae){
            SampleSwingWorker ssw = new SampleSwingWorker("text", panelA, panelB);
            ssw.execute();
        }
    }

}

public class PanelB {

    private ActionListener al;

    public PanelB(ActionListener al){
        this.al = al;
        addComponents();
    }

    private void addComponents(){
        JTextField searchField = new JTextField();
        addActionMap(searchField);
        searchField.addActionListener(al);
        //...add other components and buttons, etc, then add the listener to them too
    }

    private void addActionMap(JComponent component){
        InputMap im = component.getInputMap();
        ActionMap am = component.getActionMap();
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "HideAction");
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "HideAction");
        am.put("HideAction", new SampleAction(SampleAction.HIDE_FIELD));
    }

    private class SampleAction extends AbstractAction{

        public static final int SHOW_FIELD = 1;
        public static final int HIDE_FIELD = 2;

        private int actionType;

        public SampleAction(Object param1, Object param2, int actionType){
            this.actionType = actionType;

            //...params are for JButtons, which require name, icon, etc
            //to be passed to Action if using an Action
        }

        public void actionPerformed(ActionEvent ae){
            if(actionType == SHOW_FIELD){
                //...show the field
            }else{
                //...hide the field
            }
        }
    }
}

现在几乎所有东西都有效,剩下一个问题,这就把我带到了帖子的核心。从我的代码段中可以看出,我使用输入/动作映射将Action分配给我的搜索字段,这样按ENTER / ESCAPE将隐藏该字段。但是,当我在搜索字段中按Enter键时,它现在只触发操作,而不是动作侦听器来运行SwingWorker。

所以我想弄清楚如何让两者都发生。如何按下enter键同时触发Action和ActionListener。

另外,我在这里解释了整个过程,所以如果我只是做错了,有人可以指出我的逻辑在哪里丢失大声笑。

1 个答案:

答案 0 :(得分:1)

你的代码似乎与我有点纠结,这是一个嵌套问题。

使用ActionMapInputMap是一个不错的主意,但我希望这些操作可以调用查找面板(面板B)的find()hide()等方法

然后,ESCAPE KeyEvent可以致电hide(),ENTER KeyEvent可以连续致电find()hide()。您也可以让按钮操作指向这些方法。