在 jpanel 中随处放置
Drop everywhere in a jpanel
基于这个例子:
我有两个面板,一个拖放一个拖放,我只拖了一个副本,我不移动拖拽的图片。
代码是...
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("http://i.stack.imgur.com/gJmeJ.png")));
JLabel label2 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/8BGfi.png")));
JLabel label3 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/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);
}
}
当我将元素放在顶部面板时,元素会像这样放置在中央
我想在顶部面板的任何地方放置。
当我像这样将顶部面板设置为空布局时:p.setLayout(null);
,拖放的图像不再显示。
我不会写任何代码,因为这太烦人了,但你可以设置一个鼠标光标类型,当他们点击顶部的框时,他们会添加一个图像图标,并使用一个动作监听器来查看是否仍然按下左键单击按钮
when I drop the element on the top panel, the element is placed in the center like this
面板的默认布局管理器是 FlowLayout。
When I set the top panel to null layout ... the dropped image don't show anymore.
当您使用空布局时,您负责设置组件的大小和位置。
//p.add(new JLabel(ico));
JLabel label = new JLabel(ico);
label.setSize( label.getPreferredSize());
label.setLocation(...);
p.add(label);
您还可以使用 TransferSupport
class 获取 DropLocation
class 其中包含放置点,您可以使用设置标签的位置。
基于这个例子:
我有两个面板,一个拖放一个拖放,我只拖了一个副本,我不移动拖拽的图片。
代码是...
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("http://i.stack.imgur.com/gJmeJ.png")));
JLabel label2 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/8BGfi.png")));
JLabel label3 = new JLabel(new ImageIcon(new URL("http://i.stack.imgur.com/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);
}
}
当我将元素放在顶部面板时,元素会像这样放置在中央
我想在顶部面板的任何地方放置。
当我像这样将顶部面板设置为空布局时:p.setLayout(null);
,拖放的图像不再显示。
我不会写任何代码,因为这太烦人了,但你可以设置一个鼠标光标类型,当他们点击顶部的框时,他们会添加一个图像图标,并使用一个动作监听器来查看是否仍然按下左键单击按钮
when I drop the element on the top panel, the element is placed in the center like this
面板的默认布局管理器是 FlowLayout。
When I set the top panel to null layout ... the dropped image don't show anymore.
当您使用空布局时,您负责设置组件的大小和位置。
//p.add(new JLabel(ico));
JLabel label = new JLabel(ico);
label.setSize( label.getPreferredSize());
label.setLocation(...);
p.add(label);
您还可以使用 TransferSupport
class 获取 DropLocation
class 其中包含放置点,您可以使用设置标签的位置。