Index: javax/swing/JComponent.java =================================================================== RCS file: /cvs/gcc/gcc/libjava/javax/swing/JComponent.java,v retrieving revision 1.7.2.24 diff -u -r1.7.2.24 JComponent.java --- javax/swing/JComponent.java 10 Nov 2004 07:19:48 -0000 1.7.2.24 +++ javax/swing/JComponent.java 15 Dec 2004 09:14:03 -0000 @@ -2092,9 +2092,14 @@ * @see ComponentUI#getTransferHandler */ - void setTransferHandler (TransferHandler newHandler) + public void setTransferHandler(TransferHandler newHandler) { + if (transferHandler == newHandler) + return; + + TransferHandler oldHandler = transferHandler; transferHandler = newHandler; + firePropertyChange("transferHandler", oldHandler, newHandler); } /** Index: javax/swing/TransferHandler.java =================================================================== RCS file: /cvs/gcc/gcc/libjava/javax/swing/TransferHandler.java,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 TransferHandler.java --- javax/swing/TransferHandler.java 10 Nov 2004 07:19:48 -0000 1.1.2.2 +++ javax/swing/TransferHandler.java 15 Dec 2004 09:14:03 -0000 @@ -35,44 +35,119 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ + package javax.swing; -import java.io.Serializable; +import java.awt.event.ActionEvent; import java.awt.event.InputEvent; -import java.awt.datatransfer.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.io.Serializable; public class TransferHandler implements Serializable { + static class TransferAction extends AbstractAction + { + private String command; + + public TransferAction(String command) + { + this.command = command; + } + + public void actionPerformed(ActionEvent event) + { + JComponent component = (JComponent) event.getSource(); + TransferHandler transferHandler = component.getTransferHandler(); + Clipboard clipboard = getClipboard(component); + + if (command.equals(COMMAND_COPY)) + transferHandler.exportToClipboard(component, clipboard, COPY); + else if (command.equals(COMMAND_CUT)) + transferHandler.exportToClipboard(component, clipboard, MOVE); + else if (command.equals(COMMAND_PASTE)) + { + Transferable transferable = clipboard.getContents(null); + + if (transferable != null) + transferHandler.importData(component, transferable); + } + } + + private static Clipboard getClipboard(JComponent component) + { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) + { + try + { + sm.checkSystemClipboardAccess(); + + // We may access system clipboard. + return component.getToolkit().getSystemClipboard(); + } + catch (SecurityException e) + { + // We may not access system clipboard. + } + } + + // Create VM-local clipboard if non exists yet. + if (clipboard == null) + clipboard = new Clipboard("Clipboard"); + + return clipboard; + } + } + private static final long serialVersionUID = -7908749299918704233L; + public static final String COMMAND_COPY = "copy"; + public static final String COMMAND_CUT = "cut"; + public static final String COMMAND_PASTE = "paste"; + public static final int NONE = 0; public static final int COPY = 1; public static final int MOVE = 2; public static final int COPY_OR_MOVE = 3; - static Action getCopyAction () + private static Action copyAction = new TransferAction(COMMAND_COPY); + private static Action cutAction = new TransferAction(COMMAND_CUT); + private static Action pasteAction = new TransferAction(COMMAND_PASTE); + + /** + * Clipboard if system clipboard may not be used. + */ + private static Clipboard clipboard; + + private int sourceActions; + private Icon visualRepresentation; + + public static Action getCopyAction() { - return null; + return copyAction; } - static Action getCutAction () + public static Action getCutAction() { - return null; + return cutAction; } - static Action getPasteAction () + public static Action getPasteAction() { - return null; + return pasteAction; } - protected TransferHandler() { - // Do nothing here. + this.sourceActions = NONE; } public TransferHandler(String property) { + this.sourceActions = property != null ? COPY : NONE; } public boolean canImport (JComponent c, DataFlavor[] flavors) @@ -99,17 +174,16 @@ public int getSourceActions (JComponent c) { - return 0; + return sourceActions; } public Icon getVisualRepresentation (Transferable t) { - return null; + return visualRepresentation; } public boolean importData (JComponent c, Transferable t) { return false; } - } Index: javax/swing/text/JTextComponent.java =================================================================== RCS file: /cvs/gcc/gcc/libjava/javax/swing/text/JTextComponent.java,v retrieving revision 1.4.2.25 diff -u -r1.4.2.25 JTextComponent.java --- javax/swing/text/JTextComponent.java 23 Nov 2004 13:12:01 -0000 1.4.2.25 +++ javax/swing/text/JTextComponent.java 15 Dec 2004 09:14:03 -0000 @@ -44,8 +44,15 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.event.ActionEvent; import java.awt.event.InputMethodListener; import java.awt.event.KeyEvent; +import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; @@ -61,6 +68,7 @@ import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.Scrollable; +import javax.swing.TransferHandler; import javax.swing.UIManager; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; @@ -546,7 +554,92 @@ { parent = p; } + } + + class DefaultTransferHandler + extends TransferHandler + { + public boolean canImport(JComponent component, DataFlavor[] flavors) + { + JTextComponent textComponent = (JTextComponent) component; + + if (! (textComponent.isEnabled() + && textComponent.isEditable() + && flavors != null)) + return false; + + for (int i = 0; i < flavors.length; ++i) + if (flavors[i].equals(DataFlavor.stringFlavor)) + return true; + + return false; + } + + public void exportToClipboard(JComponent component, Clipboard clipboard, + int action) + { + JTextComponent textComponent = (JTextComponent) component; + int start = textComponent.getSelectionStart(); + int end = textComponent.getSelectionEnd(); + + if (start == end) + return; + + try + { + // Copy text to clipboard. + String data = textComponent.getDocument().getText(start, end); + StringSelection selection = new StringSelection(data); + clipboard.setContents(selection, null); + + // Delete selected text on cut action. + if (action == MOVE) + doc.remove(start, end - start); + } + catch (BadLocationException e) + { + // Ignore this and do nothing. + } + } + + public int getSourceActions() + { + return NONE; + } + + public boolean importData(JComponent component, Transferable transferable) + { + DataFlavor flavor = null; + DataFlavor[] flavors = transferable.getTransferDataFlavors(); + + if (flavors == null) + return false; + + for (int i = 0; i < flavors.length; ++i) + if (flavors[i].equals(DataFlavor.stringFlavor)) + flavor = flavors[i]; + + if (flavor == null) + return false; + + try + { + JTextComponent textComponent = (JTextComponent) component; + String data = (String) transferable.getTransferData(flavor); + textComponent.replaceSelection(data); + return true; + } + catch (IOException e) + { + // Ignored. + } + catch (UnsupportedFlavorException e) + { + // Ignored. + } + return false; + } } private static final long serialVersionUID = -8796518220218978795L; @@ -554,6 +647,7 @@ public static final String DEFAULT_KEYMAP = "default"; public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey"; + private static DefaultTransferHandler defaultTransferHandler; private static Hashtable keymaps = new Hashtable(); private Keymap keymap; @@ -1369,4 +1463,36 @@ { dragEnabled = enabled; } + + public void copy() + { + doTransferAction("copy", TransferHandler.getCopyAction()); + } + + public void cut() + { + doTransferAction("cut", TransferHandler.getCutAction()); + } + + public void paste() + { + doTransferAction("paste", TransferHandler.getPasteAction()); + } + + private void doTransferAction(String name, Action action) + { + // Install default TransferHandler if none set. + if (getTransferHandler() == null) + { + if (defaultTransferHandler == null) + defaultTransferHandler = new DefaultTransferHandler(); + + setTransferHandler(defaultTransferHandler); + } + + // Perform action. + ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, + action.getValue(Action.NAME).toString()); + action.actionPerformed(event); + } }