gpt4 book ai didi

java - 使用 TransferHandler 拖放图像

转载 作者:行者123 更新时间:2023-11-29 05:32:39 25 4
gpt4 key购买 nike

我正在尝试制作简单的 Java 应用程序以将图像拖放到 JFrame 上的 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();
}
}

最佳答案

当您使用 the constructor that takes a String 创建 TransferHandler 时,您创建了一个只能在同一 JVM 中执行传输的 TransferHandler。

new TransferHandler("text")创建一个传输 JLabel(或任何其他组件或 bean)的“文本”属性的 TransferHandler。如果要拖动图像,则需要 Image 类型的属性。 JLabel 没有 Image 类型的属性,但它有一个 Icon 类型的属性。如果您使用它,拖动源必须提供 Icon 类型的数据,并且您仍然会受到只能接受来自同一 JVM 的数据的限制。

如果您想从任何应用程序接受任何图像数据,您必须编写一个自定义的 TransferHandler。图像可以采用多种形式,但一些常见的形式是:

  1. 一个 java.awt.Image,由 DataFlavor.imageFlavor 表示.
  2. 文件列表 ( List<File> ),由 DataFlavor.javaFileListFlavor 表示.顾名思义,这通常是用户拖动文件的结果。
  3. 二进制数据(通常以 InputStream 的形式),其 MIME 类型(例如“image/png”)表示字节是图像。

那么您的自定义 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 的中心,这意味着它会填满整个框架。

关于java - 使用 TransferHandler 拖放图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20595425/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com