JDK-4335212 : RFE: Generic Interface for cut, copy, and paste
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2000-05-03
  • Updated: 2000-12-14
  • Resolved: 2000-12-14
Related Reports
Duplicate :  
Description

Name: rlT66838			Date: 05/02/2000


java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)

Right now, the standard cut, copy, and paste actions ask JTextComponent for the
last JTextComponent to have the focus, and call its appropriate cut, copy or
paste method. I need this capability in components that don't extend
JTextComponent.

For example, I've written a table, into which in which I can cut, copy and paste
a tab-delimited block of data, which is distributed across the cells. Since the
JTable doesn't (and can't) extend JTextComponent, the standard cut, copy, and
paste actions don't work on it, even though there's no reason why they
shouldn't.

I would define an interface like this:

package java.awt.datatransfer;
public interface ClipboardComponent
{
  public void cut();
  public void copy();
  public void paste();
}

(The name isn't important, but it should probably go into the datatransfer
package.)

JTextComponent should implement this interface. However, I would be free to
implement the interface in any of my components. The standard cut, copy, and
paste actions should then have a way of asking some focus manager which was the
last ClipboardComponent to have the focus  (rather than just the last
JTextComponent). This way, any of my own components that implement the interface
would automatically get access to cut, copy, and paste.

Furthermore, since the clipboard handling is done inside the cut, copy, or paste
method, this design works just as well for non-text data, such as images.

Finally, the java.awt.datatransfer package is a very useful way to describe the
different forms the transferred data may take, but it offers nothing to
determine if the focussed component is capable of receiving the data. None of
its interfaces are implemented by the JTextComponent classes or its subclasses,
so they can't be used as the needed generic interface. The Transferable
interface only describes the data, and the other two interfaces clearly don't
apply.

(There is a similar RFE, 4172946, which proposes a different solution, which I
don't like. This RFE is a clarification of an earlier RFE, 4318889, which was
closed because it didn't address the features of the datatransfer package. I
hope this RFE addresses those issues adequately.)
(Review ID: 103107) 
======================================================================

Comments
WORK AROUND Name: rlT66838 Date: 05/02/2000 Implement the interface in my own extensions of JTextField and JTextArea. Then, write a focus manager, which looks something like this: public class FocusWatcher implements AWTEventListener { private static AWTEventListener focusEar; private static WeakReference lastFocus; private static WeakReference lastClipboardComponent; private FocusWatcher() { focusEar = this; Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.FOCUS_EVENT_MASK); } public static void install() { new FocusWatcher(); } public void eventDispatched(AWTEvent event) { Object osrc = event.getSource(); if (osrc instanceof JComponent) // screens out JWindow { JComponent src = (JComponent) osrc; if (!(src instanceof JMenuItem)) { lastFocus = new WeakReference(src); if (src instanceof ClipboardComponent) lastClipboardComponent = new WeakReference(src); else if (src instanceof JTextComponent) lastClipboardComponent = new WeakReference(src); } } } public static JComponent getLastFocus() { return (JComponent)lastFocus.get(); } /** * Gets last JComponent which can be cut from or pasted into. * * @return A valid JComponent for cutting or pasting, or null if * the last valid JComponent doesn't belong to the same window as * the JComponent that triggered the ActionEvent. (This is usually a * menu or tool bar item) This way, menus and tool bars will only paste * into objects in the same window. */ public static JComponent getLastClipboardComponent(ActionEvent evt) { JComponent src = (JComponent) evt.getSource(); if (src instanceof ClipboardComponent) return src; if (src instanceof JTextComponent) return src; JRootPane oRoot; if (src instanceof JMenuItem) oRoot = ((JComponent)((JPopupMenu)src.getParent()).getInvoker()).getRootPane(); else oRoot = src.getRootPane(); JComponent lst = (JComponent) lastClipboardComponent.get(); if (lst.getRootPane() == oRoot) return lst; return null; } public static boolean hasFocus(JComponent theComp) { return lastFocus.get() == theComp; } } ======================================================================
11-06-2004

EVALUATION I believe this was added as part of the dnd work Tim added, reassigning to him for further evaluation (hopefully closing as a dup of the DnD work). scott.violet@eng 2000-12-14 This was indeed addressed by the Swing data transfer work. Closing it as a dup of the bugid for the data transfer work. timothy.prinzing@eng 2000-12-14
14-12-2000