2

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

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

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

编辑:我实际上想知道如何将其添加到菜单栏,但是对于下一个问题的答案非常好,我决定选择它作为正确答案并重命名问题.

4

3 回答 3

2

不幸的是,Swing 不支持弹出上下文菜单。你必须自己动手。幸运的是,这并不难。也许最干净的方法是安装您自己的事件队列,如此所述。那篇文章建议以下实现:

// @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; 
    } 
}

有关其他操作实现的代码,请参阅文章。

于 2012-11-27T19:54:32.857 回答
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
        }
    }
}

然后,您只需将 aClipboardMenuHandler作为侦听器添加到您的文本组件。

JTextField field = new JTextField();
ClipboardMenuHandler menuHandler = new ClipboardMenuHandler(field);
field.addMouseListener(menuHandler);
于 2012-11-27T19:54:51.973 回答
0

这对我有用:

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

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

现在,我只是MyTextField在任何地方使用,否则我会使用JTextField.

于 2015-08-07T16:05:07.057 回答