United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4276926 Please make Dragging and Dropping arrays (Like TreePath[]) work.
JDK-4276926 : Please make Dragging and Dropping arrays (Like TreePath[]) work.

Details
Type:
Bug
Submit Date:
1999-09-30
Status:
Closed
Updated Date:
2002-05-22
Project Name:
JDK
Resolved Date:
2002-05-22
Component:
client-libs
OS:
generic
Sub-Component:
java.awt
CPU:
generic
Priority:
P4
Resolution:
Not an Issue
Affected Versions:
1.2.2
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

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
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
======================================================================
                                     
2002-05-22
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.
======================================================================
                                     
2004-08-24



Hardware and Software, Engineered to Work Together