我正在尝试制作简单的Java应用程序,将图像拖放到JFabel上JLabel,但没有运气。我稍后会在我的程序中使用此功能,它将接收丢弃的图像,调整其大小然后调整亮度。制作它并保存该图像以进行进一步编辑的最简单方法是什么?
这是我的代码,它只收到删除的文本:
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.TransferHandler;
class DragNDrop extends JFrame {
JLabel label;
public DragNDrop() {
setTitle("Simple Drag & Drop");
setLayout(null);
label = new JLabel();
label.setBounds(0, 0, 200, 200);
add(label);
label.setTransferHandler(new TransferHandler("text"));
setSize(200, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new DragNDrop();
}
}
答案 0 :(得分:3)
使用the constructor that takes a String创建TransferHandler时,您创建的TransferHandler只能在同一JVM中执行传输。
new TransferHandler("text")
创建一个TransferHandler,它传输JLabel(或任何其他组件或bean)的'text'属性。如果要拖动图像,则需要Image类型的属性。 JLabel没有Image类型的属性,但它具有Icon类型的属性。如果使用它,拖动源必须提供Icon类型的数据,并且您仍然只能接受来自同一JVM的数据。
如果要接受来自任何应用程序的任何图像数据,则必须编写自定义TransferHandler。图像可以采用多种形式,但一些常见的形式是:
List<File>
),由DataFlavor.javaFileListFlavor表示。顾名思义,这通常是用户拖动文件的结果。您的自定义TransferHandler可能如下所示:
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;
}
}
一些额外的建议:在实践中,在编写功能齐全的应用程序时,您应该使用LayoutManagers。你可以从你的代码中删除setLayout(null)和label.setBounds行,你会得到完全相同的结果,因为JFrame的默认contentPane使用BorderLayout,而单参数add
方法将你的JLabel放入BorderLayout的中心,这意味着它填满了整个框架。