The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
If you are implementing cut, copy and paste using one of the Swing components that is not one of the text components you have to do some additional setup. First, you need to install the cut, copy, and paste actions in the action map. The following method shows how to do this:
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());
When you set up the Edit menu, you can also choose to add menu accelerators, so that the user can type Control-C to initiate a copy, for example. In the following code snippet, the bolded text shows how to set the menu accelerator for the cut action:
menuItem = new JMenuItem("Cut"); 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);
If you have set the menu accelerators for the CCP actions, this next step is redundant. If you have not set the menu accelerators, you need to add the CCP bindings to the input map. The following code snippet shows how this is done:
// only required if you have not set the menu accelerators 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));
Once the bindings have been installed and the Edit menu has been set up, there is another issue to be addressed: When the user initiates a cut, copy or a paste, which component should receive the action? In the case of a text component, the DefaultEditorKit
remembers which component last had the focus and forwards the action to that component. The following class, TransferActionListener
, performs the same function for non-text Swing components. This class can be dropped into most any application:
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)); } } }
Finally, you have to decide how to handle the paste. In the case of a drag and drop, you insert the data at the drop location. In the case of a paste, you do not have the benefit of the user pointing to the desired paste location. You need to decide what makes sense for your application — inserting the data before or after the current selection might be the best solution.
The following demo, ListCutPaste, shows how to implement CCP in an instance of JList
. As you can see in the screen shot there are three lists and you can cut, copy, and paste to or from any of these lists. They also support drag and drop. For this demo, the pasted data is inserted after the current selection. If there is no current selection, the data is appended to the end of the list.