[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Newsgroup Home]
|
[news.eclipse.platform.swt] Re: SWT vs SWING/AWT Drag and drop
|
This is a very useful example.
In our RCP application, we have Swing components as well as SWT/JFace. The
application already provides drag and drop support between Swing components.
Since we have added a JFace TreeViewer into the application, I am trying to
add DnD support to drag from the TreeViewer to a Swing panel. Since the drop
was not responding (nothing happened when I dropped - it did not enter the
dragSetData on the SWT side), I tried debugging, and found that it enters an
area of the code related to the DropTargetDropEvent on the swing side, where
it checks if "event.isLocalTransfer() == false", and it seems to enter that
(where it ultimately rejects the drop). According to the documentation of
"isLocalTransfer()", this should happen only when the DnD is outside of the
JVM.
In this case, the application is running on the same JVM. Swing and SWT are
running in different threads, but inside the same JVM. Does anyone know why
the DropTargetDropEvent isLocalTransfer() would return false? Is there a way
to overcome this, or could I be doing something wrong?
Thanks,
Raajesh.
"Duong Nguyen" <duongn@xxxxxxxxxx> wrote in message
news:889d377b5bf9ccae4fd6aa615343a7c1$1@xxxxxxxxxxxxxxxxxx
> Hi Sheldon,
>
> Please read my reply below:
>
>> public class CustomTransferable implements Transferable {
>
> You would need to write your own CustomTransfer class that subclasses
> ByteArrayTransfer similar to CustomTransferable:
>
> public class CustomTransfer extends ByteArrayTransfer {
>
>> protected static DataFlavor customFlavor = new DataFlavor
>> (CustomClass.class,
>> "A Custom Object");
>
> Register the type with the same id:
>
> private static final String MYTYPENAME = "A Custom Object";
> private static final int MYTYPEID = registerType (MYTYPENAME);
> private static CustomTransfer _instance = new CustomTransfer ();
>
>> protected static DataFlavor[] _supportedFlavors = { customFlavor };
>> private CustomObject _node;
>
>> public ProjectNodeTransferable(CustomObject node) {
>> this._node = node;
>> }
>
> Provide a getter for the CustomTransfer instance:
>
> public static CustomTransfer getInstance () {
> return _instance;
> }
>
>> public synchronized Object getTransferData(DataFlavor flavor)
>> throws UnsupportedFlavorException, IOException {
>> if (flavor.equals(customFlavor)) //How can SWT thread ask?
>> return _node;
>> else
>> throw new UnsupportedFlavorException(flavor);
>> }
>
>> public synchronized DataFlavor[] getTransferDataFlavors() {
>> return _supportedFlavors;
>> }
>
>> public boolean isDataFlavorSupported(DataFlavor flavor) {
>> if (flavor.equals(nodeFlavor))
>> return true;
>> return false;
>> }
>
> Validate if the object being transferred is supported by the
> CustomTransfer:
>
> protected boolean validate(Object object) {
> return false;
> }
>
> Serialize / Unserialize the object being transferred:
>
> public void javaToNative (Object object, TransferData transferData) {}
>
> public Object nativeToJava (TransferData transferData) {}
>
>
>> ================================================================
>
>> Now, my DragGestureListener starts starts a drag via s DragGestureEvent
>> and includes an instance of my above Transferable.
>
>> My question is... how can my SWT DropTarget be aware of this Transfer
>> type? I am not even sure what I need to create for my Transfer Types in
>> my drop target :
>
>> ================================================================
>> final DropTarget dropTarget = new DropTarget(chartComposite,
>> DND.DROP_COPY | DND.DROP_DEFAULT);
>> Transfer[] types = new Transfer[] { /* What Transfer is
>> compatible with CustomTransferable.getTransferData() ?? */ };
>> dropTarget.setTransfer(types);
>
> Transfer[] types = new Transfer[] {CustomTransfer.getInstance()};
>
>> ================================================================
>
>> SWT is running in a different thread than my Swing component, but all in
>> the same JVM. Does that mean I need to serialize the transfer, and
>> include a subclass of ByteArrayTransfer to do this?
>
> If you don't want to serialize your object then you can add a field to
> hold on to the object being transferred. The field can be anywhere as long
> as this class can get access to it. This transfer type will only work
> within your own application instance. It will not work with other
> instances of the same application.
>
> public Object myObject;
> public void javaToNative (Object object, TransferData transferData) {
> myObject = object;
> super.javaToNative (new byte[0], transferData); // nothing to serialize
> }
>
> public Object nativeToJava (TransferData transferData) {
> return myObject;
> }
>
> From AWT, you would get/set myObject after/before the drag-and-drop. You
> may need to null out the value of myObject after each transfer.
> In SWT, the source dragSetData and target drop method would set/get the
> transferred object the usual way:
>
> Source:
> public void dragSetData (DragSourceEvent event) {
> .......
> event.data = ...... // give it the object you want to transfer
> }
>
> Target:
> public void drop (DropTargetEvent event) {
> .......
> result = event.data;
> .......
> }
>
>> This seems like a reasonable thing to do, since I can declaritively
>> exchange objects between SWT and AWT controls with SWT_AWT. However,
>> when I involve the Drag and Drop framework; the complication grows.
>
>> I am not concerned with sharing this information external to my
>> application. It is simply to move around specific entities between Swing
>> and SWT containers.
>
>> Thanks,
>> Sheldon W
>
> For a more complete example of custom transfers, see Snippet79 and
> Snippet171.
>
> Duong
>
>