我发现在Mac OS X中运行Java程序时,文本字段对象(例如JField)使用系统剪贴板支持剪切,复制和粘贴操作,如果您使用键命令而无需执行额外的编码。例如,我可以创建一个JField,键入一些文本,选择它,然后使用" Command-C"复制它,然后将其粘贴到另一个应用程序中。同样适用于粘贴从其他应用程序复制的文本。
我真的很喜欢Java自动执行此操作,但我注意到编辑菜单不会自动显示剪切,复制和粘贴菜单项。有没有办法在选择文本时自动添加这些菜单项以访问系统剪贴板?如果不是,那么实现它们的最佳方式是什么,以便它的行为与任何其他应用程序一样。在这一点上,我只对复制和粘贴文本感兴趣。
另外,我知道系统剪贴板是特定于平台的。文本字段对象的自动系统剪贴板功能是否在其他平台上发生?
编辑:我实际上想要知道如何将其添加到菜单栏中,但是对于下一个问题我会得到如此好的答案,我决定将其选为正确的回答并重命名问题。答案 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
。