右键单击系统剪贴板操作的菜单项

时间:2012-11-27 19:41:10

标签: java clipboard menuitem

我发现在Mac OS X中运行Java程序时,文本字段对象(例如JField)使用系统剪贴板支持剪切,复制和粘贴操作,如果您使用键命令而无需执行额外的编码。例如,我可以创建一个JField,键入一些文本,选择它,然后使用" Command-C"复制它,然后将其粘贴到另一个应用程序中。同样适用于粘贴从其他应用程序复制的文本。

我真的很喜欢Java自动执行此操作,但我注意到编辑菜单不会自动显示剪切,复制和粘贴菜单项。有没有办法在选择文本时自动添加这些菜单项以访问系统剪贴板?如果不是,那么实现它们的最佳方式是什么,以便它的行为与任何其他应用程序一样。在这一点上,我只对复制和粘贴文本感兴趣。

另外,我知道系统剪贴板是特定于平台的。文本字段对象的自动系统剪贴板功能是否在其他平台上发生?

编辑:我实际上想要知道如何将其添加到菜单栏中,但是对于下一个问题我会得到如此好的答案,我决定将其选为正确的回答并重命名问题。

3 个答案:

答案 0 :(得分:2)

不幸的是,Swing不支持弹出上下文菜单。你必须自己动手。幸运的是,这并不太难。也许最干净的方法是安装自己的事件队列,如here所述。该文建议采用以下方式:

// @author Santhosh Kumar T - santhosh@in.fiorano.com 
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 - santhosh@in.fiorano.com 
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 :(得分:1)

您需要为此创建一个自定义弹出菜单,可以使用MouseListener(或MouseAdapter)和JPopupMenu来完成。我的方法是创建一个自定义鼠标监听器,您可以将其添加到任何文本组件。

public class ClipboardMenuHandler extends MouseAdapter {

    private final JTextComponent textComponent;

    public ClipboardMenuHandler(JTextComponent textComponent) {
        this.textComponent = textComponent;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.isPopupTrigger()) 
            ClipboardMenu menu = new ClipboardMenu();
            menu.show(textComponent, e.getX(), e.getY());
        }
    }

    private class ClipboardMenu extends JPopupMenu {

        public ClipboardMenu() {
            // add copy/cut/paste actions; refer to Ted's answer for PasteAction
        }
    }
}

然后,您只需将ClipboardMenuHandler添加为文本组件的监听器。

JTextField field = new JTextField();
ClipboardMenuHandler menuHandler = new ClipboardMenuHandler(field);
field.addMouseListener(menuHandler);

答案 2 :(得分:0)

这对我有用:

public class MyTextField extends JTextField {
    public static final MyPopupMenu POPUP_MENU = new MyPopupMenu();

    public MyTextField() {
        this.setComponentPopupMenu(POPUP_MENU);
    }
}

现在,我只使用MyTextField,否则我会使用JTextField