2016-02-05 45 views
1
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的完成?

+0

'问题是 - 我认为' - 调试可以告诉你究竟是否正确 – AdamSkywalker

+0

@AdamSkywalker没有错误;只是同时调用的问题。好的,我将删除“我认为的” –

+0

@AdamSkywalker当'JTextField'已经有一些文本时,'searchAction'会检测到'JTextField'不是空的并且去搜索OK。但是当'JTextField'为空时,点击menuItem,它会过去但不搜索,因为它检测到它为空。 –

回答

3

一种选择是制作一个通用的Action实现,它包含一系列需要串行操作的动作。然后遍历该列表,每次调用一个。现在使用新的实现并将其添加为动作侦听器。

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); 
3

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

操作不会同时被调用。

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

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

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

然而,听者执行的顺序为特定实现,在Java规范不能保证。所以更好的解决办法是使用联合行动。

相关问题