如何使某些动作依赖于另一个动作完成?

时间:2016-02-05 13:34:06

标签: java swing action actionlistener synchronized

Action pasteAction = new DefaultEditorKit.PasteAction();

JPopupMenu popMenu = new JPopupMenu();

menuItem = new JMenuItem();
menuItem.addActionListener(pasteAction);
menuItem.addActionListener(searchAction);
menuItem.setText("Paste & Search");

popMenu菜单显示出来;鼠标右键单击JTextField

pasteAction已做好准备。

searchAction包含检查JTextField是否为空的代码。如果它不为空,那么请搜索...

问题就是 - 我认为 - 同时调用pasteActionsearchAction。因此,无论searchAction完成其工作,都会调用pasteAction。因此,当调用searchAction来检查JTextField内容时;它发现它是空的!

如何让searchAction依赖pasteAction完成?

3 个答案:

答案 0 :(得分:3)

一个选项是创建一个通用的Action实现,它接受一系列要串行的操作。然后遍历该列表,一次调用一个。现在使用该新实现并将其添加为动作侦听器。

答案 1 :(得分:3)

正如AAG提出的那样:

/**
 * Action which allows to execute several actions as one.
 */
@SuppressWarnings("serial")
public class CombinedAction extends AbstractAction {

    /** Holds the list of actions. */
    private Action[] actions;

    /**
     * C'tor.
     * 
     * @param someActions actions which must be executed together.
     */
    public CombinedAction(String aName, Action... someActions) {
        super(aName);
        this.actions = someActions;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        for (final Action a : actions) {
            a.actionPerformed(e);
        }
    }
}

用法:

Action act = new CombinedAction("Paste and Search", pasteAction, searchAction);
menuItem = new JMenuItem(act);

答案 2 :(得分:3)

  

问题在于 - 我认为 - 同时调用了pasteAction和searchAction。

不会同时调用Actions。

从侦听器调用的所有代码都在Event Dispatch Thread (EDT)上执行。这是为了确保代码执行单线程。这是Swing最重要的概念之一,因此请务必阅读Concurrency上的Swing教程,以获取更多信息,以了解这一基本概念。

问题是侦听器代码的默认实现是以与添加侦听器相反的顺序调用侦听器。所以你可以使用:

menuItem.addActionListener(searchAction);
menuItem.addActionListener(pasteAction);

但是,侦听器执行的顺序是特定于实现的,并且在Java规范中无法保证。因此,更好的方法是使用合并的Action。