本教程是针对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实例中实现剪切、复制和粘贴功能。如屏幕截图所示,有三个列表,您可以在这些列表之间进行剪切、复制和粘贴操作。它们还支持拖放操作。对于此演示,粘贴的数据将插入到当前选择之后。如果没有当前选择,数据将追加到列表的末尾。