不幸的是,Swing不支持弹出上下文菜单。你必须推出自己的。幸运的是,这并不难。最简洁的方法可能是安装您自己的事件队列,如here所述。这篇文章提出如下实施:
// @author Santhosh Kumar T - [email protected]
public class MyEventQueue extends EventQueue{
protected void dispatchEvent(AWTEvent event){
super.dispatchEvent(event);
// interested only in mouseevents
if(!(event instanceof MouseEvent))
return;
MouseEvent me = (MouseEvent)event;
// interested only in popuptriggers
if(!me.isPopupTrigger())
return;
// me.getComponent(...) retunrs the heavy weight component on which event occured
Component comp = SwingUtilities.getDeepestComponentAt(me.getComponent(), me.getX(), me.getY());
// interested only in textcomponents
if(!(comp instanceof JTextComponent))
return;
// no popup shown by user code
if(MenuSelectionManager.defaultManager().getSelectedPath().length>0)
return;
// create popup menu and show
JTextComponent tc = (JTextComponent)comp;
JPopupMenu menu = new JPopupMenu();
menu.add(new CutAction(tc));
menu.add(new CopyAction(tc));
menu.add(new PasteAction(tc));
menu.add(new DeleteAction(tc));
menu.addSeparator();
menu.add(new SelectAllAction(tc));
Point pt = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(), tc);
menu.show(tc, pt.x, pt.y);
}
}
然后你可以使用这个:
public static void main(String[] args){
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new MyEventQueue());
.....
}
随着代码的一条线,你在你的应用程序的所有文本组件上的弹出菜单。
动作类不是太复杂。举例来说,这里的粘贴动作的执行情况,其中显示了与系统剪贴板交互:
// @author Santhosh Kumar T - [email protected]
class PasteAction extends AbstractAction{
JTextComponent comp;
public PasteAction(JTextComponent comp){
super("Paste");
this.comp = comp;
}
public void actionPerformed(ActionEvent e){
comp.paste();
}
public boolean isEnabled(){
if (comp.isEditable() && comp.isEnabled()){
Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);
return contents.isDataFlavorSupported(DataFlavor.stringFlavor);
}else
return false;
}
}
看到这篇文章的代码,其他的操作实现。
+1,你的方法更清洁,因为它自动处理* all *文本组件的菜单,而我的需要单独添加处理程序。 – Vulcan
我喜欢这种方法,但是我在您链接的文章的评论中看到,至少有一个人非常反对这种方法,因为如果事情在未来版本中发生变化,更改事件队列可能会使整个应用程序崩溃的Java。但如果文章是在2005年编写的,代码仍然有效......这是否意味着它可以安全使用? – Thunderforge
@Thunderforge - Java 1.7中显然存在一个关于安装新事件队列的错误。请参阅[此回复](http://stackoverflow.com/a/8965448/535871)以了解详细信息以及如何处理它。除此之外,我有充分理由相信这种方法是安全的。文章评论中的担忧似乎表明,拖放可能会导致问题。您可以轻松编写一个小应用程序来测试此问题。 –