好的,所以我一直在改变我的这个练习程序,我仍然坚持同样的问题。希望得到一些帮助。
注意:我正在尽我所能,使用基本代码段和简单缩写来描述我程序的各种元素。首先是基本描述,代码段将根据需要显示。
问题。在我的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。
另外,我在这里解释了整个过程,所以如果我只是做错了,有人可以指出我的逻辑在哪里丢失大声笑。
答案 0 :(得分:1)
你的代码似乎与我有点纠结,这是一个嵌套问题。
使用ActionMap
和InputMap
是一个不错的主意,但我希望这些操作可以调用查找面板(面板B)的find()
和hide()
等方法
然后,ESCAPE KeyEvent
可以致电hide()
,ENTER KeyEvent
可以连续致电find()
和hide()
。您也可以让按钮操作指向这些方法。