问题
I have a code in which I must drag two images from my desktop and drop it on a frame in two draggable buttons. The buttons have already been made on the frame. But while dragging the images, they can only be dragged to one button. The images don't get dragged to the other one. I have made a DragListener class where the dragging methods prevail and the main class DragInitialListener where I have passed objects of class DragButton so that two draggable buttons are created. I have tried everything I could think of, made two DragListener classes, passed the methods differently but the image could only be dragged in one button. I want both the buttons to be able to hold images. Please help me with it. Here's the code that I have made so far:
//This is the main class
public class DragInitialListener extends javax.swing.JFrame {
private volatile int draggedAtX, draggedAtY;
public DragInitialListener() {
initComponents();
Droptargets();
Droptarget();
}
public void Droptarget()
{
DragListener d;
DragButton db = new DragButton();
db.setSize(170,140);
d= new DragListener(db);
DropTarget drop = new DropTarget(this,d);
this.getContentPane().add(db);
}
public void Droptargets()
{
DragListener dd;
DragButton db1 = new DragButton();
db1.setSize(170,140);
dd= new DragListener(db1);
DropTarget drop1 = new DropTarget(this,dd);
this.getContentPane().add(db1);
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new DragInitialListener().setVisible(true);
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
//This is the DragListener class
public class DragListener extends JButton implements DropTargetListener
{
JButton imagebutton = new JButton();
// JButton imagebutton1 = new JButton();
private volatile int draggedAtX, draggedAtY;
DragListener(JButton image) {
imagebutton=image;
}
@Override
public void dragEnter(DropTargetDragEvent dtde) {
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
@Override
public void dragExit(DropTargetEvent dte) {
}
@Override
public void drop(DropTargetDropEvent ev) {
ev.acceptDrop(DnDConstants.ACTION_COPY);
Transferable t = ev.getTransferable();
//DropTarget test = (DropTarget) ev.getSource();
DataFlavor[] df= t.getTransferDataFlavors();
for(DataFlavor f:df)
{
try
{
if(f.isFlavorJavaFileListType())
{
List<File> files =(List<File>) t.getTransferData(f);
for(File file : files)
{
displayImage(file.getPath());
}
}
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex);
}
}
}
private void displayImage(String path)
{
BufferedImage img = null;
try
{
img =ImageIO.read(new File(path));
}
catch(Exception e)
{
}
ImageIcon icon = new ImageIcon(img);
imagebutton.setIcon(icon);
}
}
回答1:
Start simple, get one button to work, if you can get one to work, you can get 100 to work
This is a very simple example, which makes use of the transfer API, because you really only care about dropping and not dragging
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton("Drop here");
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
btn.setTransferHandler(new ImageTransferHandler());
add(btn);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public static class ImageTransferHandler extends TransferHandler {
public static final DataFlavor[] SUPPORTED_DATA_FLAVORS = new DataFlavor[]{
DataFlavor.javaFileListFlavor,
DataFlavor.imageFlavor
};
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
boolean canImport = false;
for (DataFlavor flavor : SUPPORTED_DATA_FLAVORS) {
if (support.isDataFlavorSupported(flavor)) {
canImport = true;
break;
}
}
return canImport;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Component component = support.getComponent();
if (component instanceof JButton) {
Image image = null;
if (support.isDataFlavorSupported(DataFlavor.imageFlavor)) {
image = (Image) t.getTransferData(DataFlavor.imageFlavor);
} else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
if (files.size() > 0) {
image = ImageIO.read((File) files.get(0));
}
}
ImageIcon icon = null;
if (image != null) {
icon = new ImageIcon(image);
}
((JButton) component).setIcon(icon);
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}
}
So, by doing nothing more then changing the layout and replicating the button using
public TestPane() {
setLayout(new GridLayout(5, 5));
for (int index = 0; index < 5 * 5; index++) {
JButton btn = new JButton("Drop here");
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
btn.setTransferHandler(new ImageTransferHandler());
add(btn);
}
}
I was able to achieve...
Updated...
So apparently I might have misunderstood the question, not the first time. From what's been explained to me, you might want to drag multiple images and have them applied to the buttons. Surprising, the process doesn't change that much.
In this example, I've applied the TransferHandler to the JPanel instead of the button and supplied it the buttons I want updated. You could easily update this to have a variable number of buttons, but I've started with two.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton left = makeButton("Left");
JButton right = makeButton("Right");
add(left);
add(right);
setTransferHandler(new ImageTransferHandler(left, right));
}
protected JButton makeButton(String text) {
JButton btn = new JButton(text);
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
return btn;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public static class ImageTransferHandler extends TransferHandler {
public static final DataFlavor[] SUPPORTED_DATA_FLAVORS = new DataFlavor[]{
DataFlavor.javaFileListFlavor,};
private JButton left, right;
public ImageTransferHandler(JButton left, JButton right) {
this.left = left;
this.right = right;
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
boolean canImport = false;
for (DataFlavor flavor : SUPPORTED_DATA_FLAVORS) {
if (support.isDataFlavorSupported(flavor)) {
canImport = true;
break;
}
}
return canImport;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Image image = null;
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
JButton buttons[] = new JButton[]{left, right};
for (int index = 0; index < Math.min(files.size(), 2); index++) {
if (files.size() > 0) {
image = ImageIO.read((File) files.get(index));
ImageIcon icon = null;
if (image != null) {
icon = new ImageIcon(image);
}
buttons[index].setIcon(icon);
}
}
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}
}
Now, there are rules you will need to define yourself, for example, what happens when the user only drags a single image? Do you apply it to the first button (as I have) every time, or do you try and find the button without an image and update it? What happens if all the buttons have images? Where does it go then?
Do you reject drags with more than 2 images?
来源:https://stackoverflow.com/questions/36571996/drag-two-images-and-drop-them-in-two-different-jbuttons-in-the-same-jframe