Я делаю программу для редактирования изображений на Java. Мне было интересно, можно ли перетащить изображение с рабочего стола пользователя на JPanel
и установить изображение, которое было перетащено, в качестве фона для JPanel
. Возможно ли это в Java? Если да, то как бы я это сделал?
Перетаскивание изображений
Ответы (1)
Короткий ответ: да, это возможно.
Есть несколько способов сделать это, я приведу код самого простого: перетаскивание файла изображения откуда-то в ваше Swing-приложение. Однако вы также можете скопировать изображение в буфер обмена из графического редактора и вставить его туда, но я думаю, что вам это не нужно. Чтобы реализовать этот второй вариант использования, вам придется использовать DataFlavor.imageFlavor
вместо DataFlavor.javaFileListFlavor
, как показано в моем примере. Итак, чтобы протестировать приведенный ниже код, просто добавьте экземпляр MainPanel
в контейнер и, когда приложение запустится, перетащите файлы изображений на панель.
Это реализация TransferHandler
:
import java.awt.Cursor;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
public class ImageTransferHandler extends TransferHandler {
private static final DataFlavor FILE_FLAVOR = DataFlavor.javaFileListFlavor;
private MainPanel mainPanel;
public ImageTransferHandler(MainPanel panel) {
mainPanel = panel;
}
/**
* The method to handle the transfer between the source of data and the
* destination, which is in our case the main panel.
*/
public boolean importData(JComponent c, Transferable t) {
if (canImport(c, t.getTransferDataFlavors())) {
if (transferFlavor(t.getTransferDataFlavors(), FILE_FLAVOR)) {
try {
List<File> fileList = (List<File>) t.getTransferData(FILE_FLAVOR);
if (fileList != null && fileList.toArray() instanceof File[]) {
File[] files = (File[]) fileList.toArray();
mainPanel.addFiles(files);
}
return true;
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
}
}
return false;
}
/**
* Returns the type of transfer actions to be supported.
*/
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
/**
* Specifies the actions to be performed after the data has been exported.
*/
protected void exportDone(JComponent c, Transferable data, int action) {
c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
/**
* Returns true if the specified flavor is contained in the flavors array,
* false otherwise.
*/
private boolean transferFlavor(DataFlavor[] flavors, DataFlavor flavor) {
boolean found = false;
for (int i = 0; i < flavors.length && !found; i++) {
found = flavors[i].equals(flavor);
}
return found;
}
/**
* Returns true if the component can import the specified flavours, false
* otherwise.
*/
public boolean canImport(JComponent c, DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (FILE_FLAVOR.equals(flavors[i])) {
return true;
}
}
return false;
}
}
Это панель, на которую я добавляю TransferHandler и которая отрисовывает изображение в качестве фона:
public class MainPanel extends JPanel {
private Image image;
MainPanel() {
setTransferHandler(new ImageTransferHandler(this));
}
void addFiles(File[] files) {
for (File file : files) {
try {
image = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
}
if (image != null) {
repaint();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
int width = getWidth();
int height = getHeight();
drawImage((Graphics2D) g, width, height);
}
private void drawImage(Graphics2D g2, int width, int height) {
if (image != null) {
g2.drawImage(image, 0, 0, width, height, null);
} else {
g2.drawRect(10, 10, width - 20, height - 20);
}
}
}