I have created simple component palette using JLabel with ImageIcon. That's the code of the palette item:
public class TransferableIcon extends JLabel implements Transferable {
private final Image icon;
public TransferableIcon(Image image) {
super(new ImageIcon(image));
this.icon = image;
setTransferHandler(ImageTransferHandler.getTransferHandler());
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
JComponent component = (JComponent)e.getSource();
getTransferHandler().exportAsDrag(component, e, TransferHandler.COPY);
}
});
}
private static final DataFlavor[] FLAVORS = new DataFlavor[]{ DataFlavor.imageFlavor };
@Override
public DataFlavor[] getTransferDataFlavors() {
return FLAVORS;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
boolean result = false;
for(DataFlavor dataFlavor : FLAVORS) {
if(dataFlavor.equals(flavor))
result = true;
}
return result;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if(!isDataFlavorSupported(flavor))
throw new UnsupportedFlavorException(flavor);
else
return icon;
}
}
My own TransferHandler class overrides some methods:
public class ImageTransferHandler extends TransferHandler {
private static final TransferHandler TRANSFER_HANDLER = new ImageTransferHandler();
@Override
public int getSourceActions(JComponent c) {
return TransferHandler.COPY;
}
@Override
protected Transferable createTransferable(JComponent c) {
Image image = null;
if(c instanceof JLabel) {
JLabel label = (JLabel)c;
Icon icon = label.getIcon();
image = ((ImageIcon)icon).getImage();
return new TransferableIcon(image);
}
else
throw new IllegalArgumentException("Can not transfer such a widget");
}
public static TransferHandler getTransferHandler() {
return TRANSFER_HANDLER;
}
}
I have a Visual Library scene, added to JFrame through the scene.createView()
method.
I added an AcceptAction to scene, created my own AcceptProvider, but it's accept()
method is never called: when I try to drag the TransferableIcon
to the scene, I see the "not allowed" cursor and nothing happens when I drop the icon to scene.
So, how can I enable the drop to the Scene?
The problem was not so complicated as I thought it was. In the AcceptAction class we see, that it accepts drag (and drop as well) with COPY_OR_MOVE action only. So in your own TransferHandler class you must set the exact same action:
@Override
public int getSourceActions(JComponent c) {
return TransferHandler.COPY_OR_MOVE;
}
And that's it!