【问题标题】:How to make some Action dependent on another Action's finish?如何使某个动作依赖于另一个动作的完成?
【发布时间】:2016-02-05 13:34:06
【问题描述】:
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 被同时调用。因此,无论pasteAction 是否完成其工作,都会调用searchAction。所以当searchAction被调用来检查JTextField的内容时;它发现它是空的!

如何使searchAction 依赖于pasteAction 的完成?

【问题讨论】:

  • '问题在于 - 我认为' - 调试可以准确地告诉你你是否正确
  • @AdamSkywalker 没有错误;只是同时调用的问题。好的,我将删除“我认为”
  • @AdamSkywalker 当JTextField 已经有一些文本时,searchAction 检测到JTextField 不为空并进行搜索确定。但是当JTextField为空时,点击menuItem,它会过去但不搜索,因为它检测到它是空的。
  • 我的意思是调试(或日志记录)可以显示它们是否同时执行。如果是这样,添加一个复杂的动作来保证执行顺序

标签: java swing action actionlistener synchronized


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    正如 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);
    

    【讨论】:

      【解决方案3】:

      问题在于——我认为——pasteAction 和searchAction 是同时调用的。

      动作不会同时被调用。

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

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

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

      但是,侦听器的执行顺序是特定于实现的,在 Java 规范中并不能保证。所以更好的方法是使用组合动作。

      【讨论】:

        猜你喜欢
        • 2015-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-26
        • 2011-12-30
        • 1970-01-01
        • 2014-11-11
        相关资源
        最近更新 更多