Zakaria
Zakaria

Reputation: 170

Drop everywhere in a jpanel

Based on this example : https://stackoverflow.com/a/17359895/3259386

I have two panels, one for drag and the other for drop, I just drag a copy and I don't move the dragged image.

enter image description here

the code is...

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.IOException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
import javax.swing.border.TitledBorder;

public class Test {

public static void main(String[] args) {
    createAndShowJFrame();
}

public static void createAndShowJFrame() {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {

            JFrame frame = createJFrame();
            frame.setVisible(true);

        }
    });
}

private static JFrame createJFrame() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    frame.setTitle("Test");

    JPanel panel = createEmptyJPanel();
    new MyDropTargetListener(panel);//this must be done or we wont be able to drop any image onto the empty panel

    frame.add(panel, BorderLayout.CENTER);

    try {
        frame.add(createJLabelPanel(), BorderLayout.SOUTH);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    frame.pack();

    return frame;
}

private static JPanel createEmptyJPanel() {
    final JPanel p = new JPanel() {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    };
    p.setBorder(new TitledBorder("Drag Image onto this panel"));

    TransferHandler dnd = new TransferHandler() {
        @Override
        public boolean canImport(TransferSupport support) {
            if (!support.isDrop()) {
                return false;
            }
            //only Strings
            if (!support.isDataFlavorSupported(DataFlavor.imageFlavor)) {
                return false;
            }
            return true;
        }

        @Override
        public boolean importData(TransferSupport support) {
            if (!canImport(support)) {
                return false;
            }

            Transferable tansferable = support.getTransferable();
            Icon ico;
            try {
                ico = (Icon) tansferable.getTransferData(DataFlavor.imageFlavor);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            p.add(new JLabel(ico));
            return true;
        }
    };

    p.setTransferHandler(dnd);

    return p;
}

private static JPanel createJLabelPanel() throws Exception {
    JPanel panel = new JPanel();
    panel.setBorder(new TitledBorder("Drag Image from here to Panel above"));

    JLabel label1 = new JLabel(new ImageIcon(new URL("https://i.sstatic.net/gJmeJ.png")));
    JLabel label2 = new JLabel(new ImageIcon(new URL("https://i.sstatic.net/8BGfi.png")));
    JLabel label3 = new JLabel(new ImageIcon(new URL("https://i.sstatic.net/1lgtq.png")));

    MyDragGestureListener dlistener = new MyDragGestureListener();
    DragSource ds1 = new DragSource();
    ds1.createDefaultDragGestureRecognizer(label1, DnDConstants.ACTION_COPY, dlistener);

    DragSource ds2 = new DragSource();
    ds2.createDefaultDragGestureRecognizer(label2, DnDConstants.ACTION_COPY, dlistener);

    DragSource ds3 = new DragSource();
    ds3.createDefaultDragGestureRecognizer(label3, DnDConstants.ACTION_COPY, dlistener);

    panel.add(label1);
    panel.add(label2);
    panel.add(label3);
    return panel;
}
}

class MyDropTargetListener extends DropTargetAdapter {

private DropTarget dropTarget;
private JPanel p;

public MyDropTargetListener(JPanel panel) {
    p = panel;
    dropTarget = new DropTarget(panel, DnDConstants.ACTION_COPY, this, true, null);

}

@Override
public void drop(DropTargetDropEvent event) {
    try {
        DropTarget test = (DropTarget) event.getSource();
        Component ca = (Component) test.getComponent();
        Point dropPoint = ca.getMousePosition();
        Transferable tr = event.getTransferable();

        if (event.isDataFlavorSupported(DataFlavor.imageFlavor)) {
            Icon ico = (Icon) tr.getTransferData(DataFlavor.imageFlavor);

            if (ico != null) {

                p.add(new JLabel(ico));
                p.revalidate();
                p.repaint();
                event.dropComplete(true);
            }
        } else {
            event.rejectDrop();
        }
    } catch (Exception e) {
        e.printStackTrace();
        event.rejectDrop();
    }
    }
    }

class MyDragGestureListener implements DragGestureListener {

@Override
public void dragGestureRecognized(DragGestureEvent event) {
    JLabel label = (JLabel) event.getComponent();
    final Icon ico = label.getIcon();


    Transferable transferable = new Transferable() {
        @Override
        public DataFlavor[] getTransferDataFlavors() {
            return new DataFlavor[]{DataFlavor.imageFlavor};
        }

        @Override
        public boolean isDataFlavorSupported(DataFlavor flavor) {
            if (!isDataFlavorSupported(flavor)) {
                return false;
            }
            return true;
        }

        @Override
        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
            return ico;
        }
    };
    event.startDrag(null, transferable);
}
}

when I drop the element on the top panel, the element is placed in the center like this

enter image description here

I want to drop everywhere on the top panel.

When I set the top panel to null layout like this : p.setLayout(null);, the dropped image don't show anymore.

Upvotes: 2

Views: 849

Answers (2)

camickr
camickr

Reputation: 324098

when I drop the element on the top panel, the element is placed in the center like this

The default layout manager for the panel is a FlowLayout.

When I set the top panel to null layout ... the dropped image don't show anymore.

When you use a null layout you are responsible for setting the size and location of the component.

//p.add(new JLabel(ico));
JLabel label = new JLabel(ico);
label.setSize( label.getPreferredSize());
label.setLocation(...);
p.add(label);

You can also use the TransferSupport class to get the DropLocation class which contains the drop point that you can use the set the location of the label.

Upvotes: 4

Hydrox
Hydrox

Reputation: 11

im not gonna write any code because this will be simply too annoying but you can set a mouse cursor type and make it when they click the box uptop they add a imageicon and use a actionlistener to see if there still pressing the left click button

Upvotes: 0

Related Questions