Drag'n'Drop & Using Drag Images  
Author Message
Jason Teagle





PostPosted: 2003-12-15 4:40:00 Top

java-programmer, Drag'n'Drop & Using Drag Images I have a situation where I want to be able to drag a component (or an image
of one) from one container to another. Using the excellent beginner article
at

http://java.sun.com/products/jfc/tsc/articles/dragndrop/

I have got this working in my own sample; the drag operation begins, and I
can react to the item being dropped.

The sample given uses

DragGestureEvent.startDrag(Cursor dragCursor, Transferable transferable,
DragSourceListener dsl)

This works fine, I get the change in cursor to represent the drag. Now I
want to actually have an image dragged with the cursor / in place of the
cursor (I don't mind which), so I adapted my working sample to instead use

DragGestureEvent.startDrag(Cursor dragCursor, Image dragImage, Point
imageOffset, Transferable transferable, DragSourceListener dsl)

However, there is no change: no image is dragged, it still just changes the
cursor. No exceptions are generated, and the drag still proceeds as normal.
I can see that the Image object (whose reference is being passed) is valid.
I tried a Point of (10, 10) (not sure whether this represents cursor hotspot
offset from image top-left or vice versa, or even something entirely
different) and of (0, 0) instead when that didn't work ( (0, 0) seems safe
in all cases).

I delved into the source code just a little to see if there was anything
obvious, such as the image needing to be of a specific size or format or
something; a cursory glance only shows that the image gets passed down the
line, and there are no comments on whether it should be a special type of
image or just any old image.

So I'm a little stuck. Anyone got any ideas for why it doesn't use the
supplied image? Have I missed a step?

WinXP Pro SP1
Java 1.4.2_03


--

 
ak





PostPosted: 2003-12-15 7:26:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images ensure that you really loaded your image (use MediaTracker);

____________

http://reader.imagero.com the best java image reader.


 
Jason Teagle





PostPosted: 2003-12-15 19:25:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > ensure that you really loaded your image (use MediaTracker);

Thanks, but as I already mentioned, I know it's valid; it's loaded using an
ImageIcon (which automatically uses a MediaTracker internally), which blocks
until it has loaded or failed, and I have actually examined the object(s)
using Eclipse to verify that it actually has an image in it.

Just to make absolutely sure it hadn't done something stupid like get the
image's header and not the data bits, I just tried drawing the image on the
panel that contains the item to drag - and it shows - final proof that the
image is loaded. But it still isn't used in the drag {:v(


--

 
 
ak





PostPosted: 2003-12-16 4:19:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images please post working example

____________

http://reader.imagero.com the best java image reader.


 
 
Jason Teagle





PostPosted: 2003-12-16 6:07:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > please post working example

By "working" I assume you mean compilable, since if it was "working" I
wouldn't need to ask here {:v)

The "littleducky.gif" mentioned in JSourcePanel is a 16x16 non-transparent
GIF. I originally used a bigger image, but it occurred to me that perhaps
the drag image had to be no bigger than a standard system cursor - hence the
reduction. Assuming that you supply a valid image (I refrain from trying to
include attachments here), note that it renders quite happily in the source
panel on the left, proving that it is loaded OK. The red square in the
source panel is what can be dragged to the right panel, and it should pop up
a message box saying "Why, thankyou!" if you drop it successfully. I only
see the drag cursor, not the image I specify also being dragged as expected.

4 files' worth, each in separate sections:
---
public class JDnDFrame extends JFrame
{
public static void main(String[] args)
{
JDnDFrame mainFrame ;

mainFrame = new JDnDFrame();
}

private JDestinationPanel m_destPanel ;
private JSourcePanel m_sourcePanel ;

public JDnDFrame()
{
super("TestDnD");
setBounds(100, 100, 400, 300);
buildUI();
setVisible(true);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
onClose();
}
}
);
}

private void onClose()
{
setVisible(false);
System.exit(0);
}

private void buildUI()
{
Container contentPane ;
GridBagConstraints gridData ;

contentPane = getContentPane();
gridData = new GridBagConstraints();
if (contentPane != null && gridData != null)
{
contentPane.setLayout(new GridBagLayout() );
contentPane.setBackground(new Color(192, 192, 192) );

gridData.fill = GridBagConstraints.BOTH ;
gridData.insets = new Insets(8, 8, 8, 8);
gridData.weightx = 0.5 ;
gridData.weighty = 1.0 ;

gridData.gridx = 0 ;
gridData.gridy = 0 ;
m_sourcePanel = new JSourcePanel();
contentPane.add(m_sourcePanel, gridData);

gridData.gridx = 1 ;
gridData.gridy = 0 ;
m_destPanel = new JDestinationPanel();
contentPane.add(m_destPanel, gridData);

m_sourcePanel.add(m_sourcePanel.getDragPanel() );
}
}

}

---
public class JSourcePanel extends JPanel implements DragGestureListener,
DragSourceListener
{
private ImageIcon m_dragImage ;
private JDragPanel m_dragPanel ;

public JSourcePanel()
{
DragSource dragSource ;

m_dragImage = new ImageIcon("littleducky.gif");
m_dragPanel = new JDragPanel();

setBackground(new Color(0, 0, 0) );
setPreferredSize(new Dimension(150, 100) );

dragSource = DragSource.getDefaultDragSource();
dragSource.createDefaultDragGestureRecognizer(this,
DnDConstants.ACTION_MOVE,
this);
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);

g.setColor(new Color(255, 255, 255) );
g.drawString("Source", 50, 50);

// Prove that the image is loaded OK by rendering it manually.
g.drawImage(m_dragImage.getImage(), 10, 10, new Color(0, 0, 0), this);
}

public JDragPanel getDragPanel()
{
return m_dragPanel ;
}

public void dragGestureRecognized(DragGestureEvent e)
{
Image x = m_dragImage.getImage();
// This was used to verify that the image was valid by examining 'x' in
Eclipse.

try
{
// This is where the image passed seems to get ignored.
e.startDrag(DragSource.DefaultMoveDrop, m_dragImage.getImage(),
new Point(0, 0), m_dragPanel, this);
}
catch(InvalidDnDOperationException e2)
{
e2.printStackTrace();
}
}

public void dragDropEnd(DragSourceDropEvent e) {}
public void dragEnter(DragSourceDragEvent e) {}
public void dragExit(DragSourceEvent e) {}
public void dragOver(DragSourceDragEvent e) {}
public void dropActionChanged(DragSourceDragEvent e) {}
}

---
public class JDestinationPanel extends JPanel implements DropTargetListener
{
private DropTarget m_dropTarget ;

public JDestinationPanel()
{
m_dropTarget = new DropTarget(this, DnDConstants.ACTION_MOVE, this);

setBackground(new Color(0, 0, 0) );
setPreferredSize(new Dimension(150, 100) );
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);

g.setColor(new Color(255, 255, 255) );
g.drawString("Destination", 50, 50);
}

public void drop(DropTargetDropEvent e)
{
DataFlavor theFlavour ;
Object transferredObject ;
Transferable transferData ;

try
{
theFlavour = JDragPanel.getTheSupportedFlavour();
transferData = e.getTransferable();
if (e.isDataFlavorSupported(theFlavour) )
{
transferredObject = transferData.getTransferData(theFlavour);
e.acceptDrop(DnDConstants.ACTION_MOVE);
e.dropComplete(true);
JOptionPane.showMessageDialog(this,"Why thankyou!");
}
else
{
e.rejectDrop();
}
}
catch(IOException e2)
{
e2.printStackTrace();
}
catch(UnsupportedFlavorException e3)
{
e3.printStackTrace();
}
}

public void dragEnter(DropTargetDragEvent e) { }
public void dragExit(DropTargetEvent e) { }
public void dragOver(DropTargetDragEvent e) { }
public void dropActionChanged(DropTargetDragEvent e) { }

}

---
public class JDragPanel extends JPanel implements Transferable
{
private static DataFlavor[] m_supportedFlavours ;

public JDragPanel()
{
setBackground(new Color(255, 0, 0) );
setPreferredSize(new Dimension(25, 25) );

m_supportedFlavours = new DataFlavor[1];
if (m_supportedFlavours != null)
m_supportedFlavours[0] = new DataFlavor(getClass(),"JDragPanel");

}

public DataFlavor[] getTransferDataFlavors()
{
return m_supportedFlavours ;
}

public boolean isDataFlavorSupported(DataFlavor flavour)
{
return flavour.equals(m_supportedFlavours[0] );
}

public Object getTransferData(DataFlavor flavour) throws
UnsupportedFlavorException, IOException
{
return this ;
}

public static DataFlavor getTheSupportedFlavour()
{
return m_supportedFlavours[0];
}

}


--

 
 
ak





PostPosted: 2003-12-16 16:55:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images I found that drag image is platform specific issue.
you can check if it is supported for current platform by calling
DragSource.isDragImageSupported().

I think you could create custom Cursor from your image and show it instead
of image.

Toolkit.getDefaultToolkit().createCustomCursor(Image cursor, Point hotSpot,
String name);

If the image to display is invalid, the cursor will be hidden (made
completely transparent), and the hotspot will be set to (0, 0).

____________

http://reader.imagero.com the best java image reader.


 
 
Jason Teagle





PostPosted: 2003-12-17 22:21:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > I found that drag image is platform specific issue.
> you can check if it is supported for current platform by calling
> DragSource.isDragImageSupported().
>
> I think you could create custom Cursor from your image and show it instead
> of image.
>
> Toolkit.getDefaultToolkit().createCustomCursor(Image cursor, Point
hotSpot,
> String name);
>
> If the image to display is invalid, the cursor will be hidden (made
> completely transparent), and the hotspot will be set to (0, 0).

Very interesting, thanks for your interest. I'm 99.99% convinced WinXP
should support it since if you drag files from Windows Explorer, a
semi-transparent image of the file name rectangles is used... but it may be
that Sun's Java implementation on Windows doesn't support the feature.

I will definitely try the custom cursor alternative, that sounds promising.


--

 
 
Jason Teagle





PostPosted: 2003-12-18 5:49:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > I think you could create custom Cursor from your image and show it instead
> of image.
>
> Toolkit.getDefaultToolkit().createCustomCursor(Image cursor, Point
hotSpot,
> String name);
>
> If the image to display is invalid, the cursor will be hidden (made
> completely transparent), and the hotspot will be set to (0, 0).

The custom cursor approach certainly does work under XP Pro. It is forced
(squashed or stretched) to a specific size, but this is acceptable for what
I want. Not sure why it does it, but I can live with it - it does the job
still. I just hope it works under other OSs {:v)


--

 
 
google.1.SteveCrook





PostPosted: 2003-12-18 20:03:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images Take a look at this article:

http://www.javaworld.com/javatips/jw-javatip114_p.html
 
 
ak





PostPosted: 2003-12-19 2:18:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > The custom cursor approach certainly does work under XP Pro. It is forced
> (squashed or stretched) to a specific size, but this is acceptable for
what
> I want. Not sure why it does it, but I can live with it - it does the job
still.

I think you need image 32x32 pixels.
Othirwise it is stretched to this size and looks rough.

> I just hope it works under other OSs {:v)
sure
____________

http://reader.imagero.com the best java image reader.


 
 
ak





PostPosted: 2003-12-19 2:23:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images this works only within java!
If you drag it outside... no ghost image.
____________

http://reader.imagero.com the best java image reader.


 
 
Jason Teagle





PostPosted: 2003-12-19 5:40:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > Take a look at this article:
>
> http://www.javaworld.com/javatips/jw-javatip114_p.html

Looks good! Thanks.


--

 
 
Jason Teagle





PostPosted: 2003-12-19 5:41:00 Top

java-programmer >> Drag'n'Drop & Using Drag Images > this works only within java!
> If you drag it outside... no ghost image.

That is OK for me in this specific case, but it's worth noting.


--