JDK-4276926 : Please make Dragging and Dropping arrays (Like TreePath[]) work.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.2.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 1999-09-30
  • Updated: 2002-05-22
  • Resolved: 2002-05-22
Related Reports
Relates :  
Relates :  
Description

Name: krT82822			Date: 09/29/99


(see revised/expanded test case below)

This is the Transferable I used to create a generic
way to drag and drop objects within a single application.
I tried passing a TreePath[] to the constructor, but
there is an exception, and the message says "failed to parse."
I think there is a problem with the MimeType parsing
for arrays.

class ObjectTransferable implements Transferable {
        Object obj;
        DataFlavor flavor;
        DataFlavor [] flavors = new DataFlavor[1];

        public ObjectTransferable(Object o) throws ClassNotFoundException {
                obj = o;
                flavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+"; class="+obj.getClass().getName());
                flavors[0] = flavor;
        }
        public Object getTransferData(DataFlavor df) {
                return obj;
        }
        public DataFlavor[] getTransferDataFlavors() {
                return flavors;
        }
        public boolean isDataFlavorSupported(DataFlavor df) {
                for (int i = 0; i < flavors.length; i++) {
                        if (df.equals(flavors[i])) {
                                return true;
                        }
                }
                return false;
        }
}
java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, sunwjit)
java full version "JDK-1.2.2-W"

----------------------

9/29/99 add'l feedback from user:

Well, I can't spare the time either, but in order to improve YOUR 
product, I have included a full test case.  See attachment.

I have a work around.  Simply convert your array to a Vector or
other List.  I haven't actually tried this, but I am fairly confident
that it would work.

I guess I'm not even sure that passing an array around in a Transferable
is even possible...

-------------------

9/29/99 REVISED TEST CASE:

import java.awt.datatransfer.*;

class ObjectTransferable implements Transferable {
        Object obj;
        DataFlavor flavor;
        DataFlavor [] flavors = new DataFlavor[1];

        public ObjectTransferable(Object o) throws ClassNotFoundException {
                obj = o;
                flavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+"; class="+obj.getClass().getName());
                flavors[0] = flavor;
        }
        public Object getTransferData(DataFlavor df) {
                return obj;
        }
        public DataFlavor[] getTransferDataFlavors() {
                return flavors;
        }
        public boolean isDataFlavorSupported(DataFlavor df) {
                for (int i = 0; i < flavors.length; i++) {
                        if (df.equals(flavors[i])) {
                                return true;
                        }
                }
                return false;
        }
        static public void main (String [] args) {
                try {
                        System.err.println("This works");
                        new ObjectTransferable(new String());
                        System.err.println("This doesnt");
                        new ObjectTransferable(new String[5]);
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}


(Review ID: 95871) 
======================================================================

Comments
WORK AROUND Name: krT82822 Date: 09/29/99 I imagine one could convert the array to a list and pass the list instead. ----------- Simply convert your array to a Vector or other List. I haven't actually tried this, but I am fairly confident that it would work. ======================================================================
24-08-2004

EVALUATION Reproducible with merlin build 25. david.mendenhall@eng 2000-08-03 Name: agR10216 Date: 05/22/2002 The mimeType parameter of the DataFlavor constructor should represent a MIME type as defined in RFC 2045 and 2046. RFC 2045 prescribes that a parameter value that contains special characters must be quoted. The string passed to the DataFlavor constructor in the test case contains special characters ('[' and ';') in the "class" parameter value (the class name is '[Ljava.lang.String;'), however the value is not quoted, so this string doesn't represent a valid MIME type. If the test case is modified, so that the MIME type string passed to the DataFlavor constructor conforms to the RFCs mentioned above, the exception is not thrown and the constructed DataFlavor can be used for data transfer. The following application demonstrates dragging and dropping of arrays. Try to drag from one green panel and drop on another green panel. ---------------------------------------------------------------------------------------- import java.awt.*; import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.event.*; public class ArrayDnD extends Panel { public ArrayDnD() { setBackground(Color.GREEN); DragGestureListener dragGestureListener = new DragGestureListener() { public void dragGestureRecognized(DragGestureEvent dge) { dge.startDrag(null, new ArraySelection(new String[] { "" + System.currentTimeMillis(), "" + System.currentTimeMillis(), "" + System.currentTimeMillis() }), null ); } }; new DragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, dragGestureListener); DropTargetAdapter dropTargetAdapter = new DropTargetAdapter() { public void drop(DropTargetDropEvent dtde) { Transferable t = dtde.getTransferable(); if (t.isDataFlavorSupported(ArraySelection.localObjectFlavor)) { dtde.acceptDrop(DnDConstants.ACTION_COPY); try { String[] vec = (String[]) t.getTransferData(ArraySelection.localObjectFlavor); for (int i = 0; i < vec.length; i++) { System.err.print(vec[i] + " "); } System.err.println(); dtde.dropComplete(true); } catch (Exception e) { dtde.dropComplete(false); } } else { System.err.println("localObjectFlavor is not supported by Transferable"); dtde.rejectDrop(); } } }; new DropTarget(this, dropTargetAdapter); } public static void main(String[] args) { System.err.println(ArraySelection.localObjectFlavor); Frame frame = new Frame(); frame.setLayout(new GridLayout(1, 0)); frame.add(new ArrayDnD()); frame.add(new Panel()); frame.add(new ArrayDnD()); frame.setSize(200, 200); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } } class ArraySelection implements Transferable { public static DataFlavor localObjectFlavor; static { try { localObjectFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + "; class=" + "\"" + (new String[0]).getClass().getName() + "\""); } catch (ClassNotFoundException e) { // can not occur e.printStackTrace(); } } private static DataFlavor[] flavors = { localObjectFlavor }; private String[] data; public ArraySelection(String[] data) { this.data = data; } public DataFlavor[] getTransferDataFlavors() { return (DataFlavor[])flavors.clone(); } public boolean isDataFlavorSupported(DataFlavor flavor) { for (int i = 0; i < flavors.length; i++) { if (flavor.equals(flavors[i])) { return true; } } return false; } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, java.io.IOException { if (flavor.equals(flavors[0])) { return (Object)data; } else { throw new UnsupportedFlavorException(flavor); } } } ---------------------------------------------------------------------------------------- So the problem documented in this bug report is not a bug. ###@###.### 2002-05-22 ======================================================================
22-05-2002