Java Forum / GUI / December 2003
Drag'n'Drop & Using Drag Images
Jason Teagle - 14 Dec 2003 20:39 GMT 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
 Signature -- Jason Teagle jason@teagster.co.uk
ak - 14 Dec 2003 23:26 GMT ensure that you really loaded your image (use MediaTracker);
--
____________
http://reader.imagero.com the best java image reader.
Jason Teagle - 15 Dec 2003 11:24 GMT > 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(
 Signature -- Jason Teagle jason@teagster.co.uk
ak - 15 Dec 2003 20:19 GMT please post working example
--
____________
http://reader.imagero.com the best java image reader.
Jason Teagle - 15 Dec 2003 22:07 GMT > 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]; }
}
 Signature -- Jason Teagle jason@teagster.co.uk
ak - 16 Dec 2003 08:55 GMT 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 - 17 Dec 2003 14:21 GMT > I found that drag image is platform specific issue. > you can check if it is supported for current platform by calling [quoted text clipped - 8 lines] > 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.
 Signature -- Jason Teagle jason@teagster.co.uk
Jason Teagle - 17 Dec 2003 21:48 GMT > I think you could create custom Cursor from your image and show it instead > of image. [quoted text clipped - 4 lines] > 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)
 Signature -- Jason Teagle jason@teagster.co.uk
ak - 18 Dec 2003 18:17 GMT > 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.
SPC - 18 Dec 2003 12:02 GMT Take a look at this article:
http://www.javaworld.com/javatips/jw-javatip114_p.html
ak - 18 Dec 2003 18:23 GMT this works only within java! If you drag it outside... no ghost image. ____________
http://reader.imagero.com the best java image reader.
Jason Teagle - 18 Dec 2003 21:40 GMT > 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.
 Signature -- Jason Teagle jason@teagster.co.uk
Jason Teagle - 18 Dec 2003 21:40 GMT > Take a look at this article: > > http://www.javaworld.com/javatips/jw-javatip114_p.html Looks good! Thanks.
 Signature -- Jason Teagle jason@teagster.co.uk
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|