When you create a TransferHandler using the constructor that takes a String, you create a TransferHandler that can only perform transfers within the same JVM.
new TransferHandler("text")
creates a TransferHandler that transfers the 'text' property of JLabel (or any other component or bean). If you want to drag images, you need a property of type Image. JLabel has no properties of type Image, but it has a property of type Icon. If you use that, the drag source must supply data of type Icon, and you will still have the limitation of only accepting data from the same JVM.
If you want to accept any Image data from any application, you must write a custom TransferHandler. Images can take a number of forms, but some common forms are:
- A java.awt.Image, represented by DataFlavor.imageFlavor.
- A List of Files (
List<File>
), represented by DataFlavor.javaFileListFlavor. As the name suggests, this usually is the result of the user's dragging files.
- Binary data (usually in the form of an InputStream) whose MIME type (such as "image/png") indicates the bytes are an image.
Your custom TransferHandler, then, might look like this:
private static class ImageHandler
extends TransferHandler {
private static final long serialVersionUID = 1;
private boolean isReadableByImageIO(DataFlavor flavor) {
Iterator<?> readers = ImageIO.getImageReadersByMIMEType(
flavor.getMimeType());
if (readers.hasNext()) {
Class<?> cls = flavor.getRepresentationClass();
return (InputStream.class.isAssignableFrom(cls) ||
URL.class.isAssignableFrom(cls) ||
File.class.isAssignableFrom(cls));
}
return false;
}
@Override
public boolean canImport(TransferSupport support) {
if (support.getUserDropAction() == LINK) {
return false;
}
for (DataFlavor flavor : support.getDataFlavors()) {
if (flavor.equals(DataFlavor.imageFlavor) ||
flavor.equals(DataFlavor.javaFileListFlavor) ||
isReadableByImageIO(flavor)) {
return true;
}
}
return false;
}
@Override
public boolean importData(TransferSupport support) {
if (!(support.getComponent() instanceof JLabel)) {
return false;
}
if (!canImport(support)) {
return false;
}
// There are three types of DataFlavor to check:
// 1. A java.awt.Image object (DataFlavor.imageFlavor)
// 2. A List<File> object (DataFlavor.javaFileListFlavor)
// 3. Binary data with an image/* MIME type.
if (support.isDataFlavorSupported(DataFlavor.imageFlavor)) {
try {
Image image = (Image)
support.getTransferable().getTransferData(
DataFlavor.imageFlavor);
JLabel label = (JLabel) support.getComponent();
label.setIcon(new ImageIcon(image));
return true;
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
try {
Iterable<?> list = (Iterable<?>)
support.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
Iterator<?> files = list.iterator();
if (files.hasNext()) {
File file = (File) files.next();
Image image = ImageIO.read(file);
JLabel label = (JLabel) support.getComponent();
label.setIcon(new ImageIcon(image));
return true;
}
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
for (DataFlavor flavor : support.getDataFlavors()) {
if (isReadableByImageIO(flavor)) {
try {
Image image;
Object data =
support.getTransferable().getTransferData(flavor);
if (data instanceof URL) {
image = ImageIO.read((URL) data);
} else if (data instanceof File) {
image = ImageIO.read((File) data);
} else {
image = ImageIO.read((InputStream) data);
}
JLabel label = (JLabel) support.getComponent();
label.setIcon(new ImageIcon(image));
return true;
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
}
}
return false;
}
}
Some additional advice: In practice, when writing a full-featured application, you should be using LayoutManagers. You could remove the setLayout(null) and label.setBounds lines from your code, and you would get exactly the same result, because a JFrame's default contentPane uses a BorderLayout, and the single-argument add
method places your JLabel in the center of that BorderLayout, which means it fills the entire frame.