本教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本引入的改进,并可能使用已不再可用的技术。
请参阅Java语言更改以了解Java SE 9及后续版本中更新的语言特性的摘要。
请参阅JDK发行说明,以获取有关所有JDK版本的新功能、增强功能以及已删除或不推荐选项的信息。
如果你正在使用 Swing 组件之一来实现剪切、复制和粘贴功能,而不是使用文本组件,你需要进行一些额外的设置。首先,你需要在操作映射中安装剪切、复制和粘贴操作。下面的方法展示了如何进行此设置:
private void setMappings(JList list) { ActionMap map = list.getActionMap(); map.put(TransferHandler.getCutAction().getValue(Action.NAME), TransferHandler.getCutAction()); map.put(TransferHandler.getCopyAction().getValue(Action.NAME), TransferHandler.getCopyAction()); map.put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction());
当设置编辑菜单时,你也可以选择添加菜单快捷键,这样用户就可以使用 Control-C 进行复制,例如。在下面的代码片段中,加粗的文本展示了如何为剪切操作设置菜单快捷键:
menuItem = new JMenuItem("剪切"); menuItem.setActionCommand((String)TransferHandler.getCutAction(). getValue(Action.NAME)); menuItem.addActionListener(actionListener); menuItem.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK)); menuItem.setMnemonic(KeyEvent.VK_T); mainMenu.add(menuItem);
如果你已经为剪切、复制和粘贴操作设置了菜单快捷键,那么下一步就是多余的。如果你没有设置菜单快捷键,你需要将剪切、复制和粘贴操作绑定到输入映射中。下面的代码片段展示了如何完成这个操作:
// 仅在没有设置菜单快捷键时才需要 InputMap imap = this.getInputMap(); imap.put(KeyStroke.getKeyStroke("ctrl X"), TransferHandler.getCutAction().getValue(Action.NAME)); imap.put(KeyStroke.getKeyStroke("ctrl C"), TransferHandler.getCopyAction().getValue(Action.NAME)); imap.put(KeyStroke.getKeyStroke("ctrl V"), TransferHandler.getPasteAction().getValue(Action.NAME));
一旦绑定安装完毕并设置了编辑菜单,还有一个问题需要解决:当用户进行剪切、复制或粘贴操作时,哪个组件应该接收该操作?对于文本组件,DefaultEditorKit
会记住上次拥有焦点的组件,并将操作转发给该组件。下面的 TransferActionListener
类为非文本的 Swing 组件执行相同的功能。这个类可以在大多数应用程序中使用:
public class TransferActionListener implements ActionListener, PropertyChangeListener { private JComponent focusOwner = null; public TransferActionListener() { KeyboardFocusManager manager = KeyboardFocusManager. getCurrentKeyboardFocusManager(); manager.addPropertyChangeListener("permanentFocusOwner", this); } public void propertyChange(PropertyChangeEvent e) { Object o = e.getNewValue(); if (o instanceof JComponent) { focusOwner = (JComponent)o; } else { focusOwner = null; } } public void actionPerformed(ActionEvent e) { if (focusOwner == null) return; String action = (String)e.getActionCommand(); Action a = focusOwner.getActionMap().get(action); if (a != null) { a.actionPerformed(new ActionEvent(focusOwner, ActionEvent.ACTION_PERFORMED, null)); } } }
最后,您需要决定如何处理粘贴操作。对于拖放操作,您将数据插入到放置位置。对于粘贴操作,您无法确定用户所需粘贴的位置。您需要决定对您的应用程序来说什么是合理的解决方案 - 在当前选择之前还是之后插入数据可能是最好的解决方案。
下面的演示示例ListCutPaste展示了如何在JList
实例中实现剪切、复制和粘贴功能。如屏幕截图所示,有三个列表,您可以在这些列表之间进行剪切、复制和粘贴操作。它们还支持拖放操作。对于此演示,粘贴的数据将插入到当前选择之后。如果没有当前选择,数据将追加到列表的末尾。