[英]how to drag and drop table, combobox , radio button , textfield and textarea from toolbar to textpane in java?
[英]How to make button clickable and textfield editable in my Java drag and drop app?
我正在学习 Java Swing 中的拖放功能,所以我修改了一个示例应用程序,如下所示:
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import java.util.Arrays;
import javax.activation.*;
import javax.swing.*;
public class Demo_Drag_And_Drop_Panel extends JPanel
{
public Demo_Drag_And_Drop_Panel()
{
DefaultListModel<Item_Panel> m=new DefaultListModel<>();
for (String s : Arrays.asList("error","information","question","warning")) m.addElement(new Item_Panel(s));
JList<Item_Panel> list=new JList<>(m);
list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
list.setTransferHandler(new ListItem_TransferHandler());
list.setDropMode(DropMode.INSERT);
list.setDragEnabled(true);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP); // http://java-swing-tips.blogspot.jp/2008/10/rubber-band-selection-drag-and-drop.html
list.setVisibleRowCount(0);
list.setFixedCellWidth(300);
list.setFixedCellHeight(36);
list.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
list.setCellRenderer(new ListCellRenderer<Item_Panel>()
{
// private final JPanel p=new JPanel(new BorderLayout());
private final JPanel p=new JPanel(new FlowLayout(0,1,1));
JLabel icon=new JLabel((Icon)null,JLabel.CENTER);
JButton button=new JButton();
JLabel label=new JLabel();
JTextField textField=new JTextField();
@Override public Component getListCellRendererComponent(JList list,Item_Panel value,int index,boolean isSelected,boolean cellHasFocus)
{
icon.setIcon(value.icon);
button.setText(value.button.getText());
button.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if ((e.getModifiers() & InputEvent.BUTTON1_MASK)!=0)
{
// Out("mouseClicked : Left");
Out(value.name);
}
else if ((e.getModifiers() & InputEvent.BUTTON2_MASK)!=0)
{
// Out("mouseClicked : Middle");
}
else if ((e.getModifiers() & InputEvent.BUTTON3_MASK)!=0)
{
// Out("mouseClicked : Right");
}
}
});
label.setText(value.name);
label.setForeground(isSelected?list.getSelectionForeground():list.getForeground());
textField.setText(value.textField.getText());
textField.setEditable(true);
p.add(icon);
p.add(button);
p.add(label);
p.add(textField);
p.setBackground(isSelected?list.getSelectionBackground():list.getBackground());
return p;
}
});
add(new JScrollPane(list));
}
private static void out(String message) { System.out.print(message); }
private static void Out(String message) { System.out.println(message); }
public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); }
public static void createAndShowGUI()
{
JFrame f=new JFrame("Demo_Drag_And_Drop_Panel");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Demo_Drag_And_Drop_Panel());
f.setSize(350,213);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class Item_Panel
{
public final String name;
public final Icon icon;
public final JButton button;
public final JTextField textField;
public Item_Panel(String name)
{
this.name=name;
icon=UIManager.getIcon("OptionPane."+name+"Icon");
button=new JButton(name);
textField=new JTextField(name);
}
}
//@camickr already suggested above.
//http://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html
class ListItem_TransferHandler extends TransferHandler
{
private final DataFlavor localObjectFlavor;
private Object[] transferedObjects=null;
public ListItem_TransferHandler() { localObjectFlavor=new ActivationDataFlavor(Object[].class,DataFlavor.javaJVMLocalObjectMimeType,"Array of items"); }
@SuppressWarnings("deprecation")
@Override protected Transferable createTransferable(JComponent c)
{
JList list=(JList)c;
indices=list.getSelectedIndices();
transferedObjects=list.getSelectedValues();
return new DataHandler(transferedObjects,localObjectFlavor.getMimeType());
}
@Override public boolean canImport(TransferSupport info)
{
if (!info.isDrop() || !info.isDataFlavorSupported(localObjectFlavor)) return false;
return true;
}
@Override public int getSourceActions(JComponent c)
{
return MOVE; //TransferHandler.COPY_OR_MOVE;
}
@SuppressWarnings("unchecked")
@Override public boolean importData(TransferSupport info)
{
if (!canImport(info)) return false;
JList target=(JList)info.getComponent();
JList.DropLocation dl=(JList.DropLocation)info.getDropLocation();
DefaultListModel listModel=(DefaultListModel)target.getModel();
int index=dl.getIndex();
int max=listModel.getSize();
if (index<0||index>max) index=max;
addIndex=index;
try
{
Object[] values=(Object[])info.getTransferable().getTransferData(localObjectFlavor);
addCount=values.length;
for (int i=0;i<values.length;i++)
{
int idx=index++;
listModel.add(idx,values[i]);
target.addSelectionInterval(idx,idx);
}
return true;
}
catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); }
catch (IOException ioe) { ioe.printStackTrace(); }
return false;
}
@Override protected void exportDone(JComponent c,Transferable data,int action) { cleanup(c,action==MOVE); }
private void cleanup(JComponent c,boolean remove)
{
if (remove&&indices!=null)
{
JList source=(JList)c;
DefaultListModel model=(DefaultListModel)source.getModel();
if (addCount>0)
{
//http://java-swing-tips.googlecode.com/svn/trunk/DnDReorderList/src/java/example/MainPanel.java
for (int i=0;i<indices.length;i++) if (indices[i]>=addIndex) indices[i]+=addCount;
}
for (int i=indices.length-1;i>=0;i--)
{
model.remove(indices[i]);
}
}
indices=null;
addCount=0;
addIndex=-1;
}
private int[] indices=null;
private int addIndex=-1; //Location where items were added
private int addCount=0; //Number of items added.
}
但是当我运行它时,我注意到按钮不可点击并且文本字段不可编辑,如何修复它们? 换句话说,我希望能够单击按钮和 output 一些信息并能够单击文本字段并编辑其中的文本,该怎么做?
JList
不支持“可食用性”。 渲染只不过是涂在组件表面上的“橡皮图章”。
现在,拖放不是“简单”的 API,它需要一些工作才能使其正常工作(大量的锅炉电镀)
重要的是,您应该注意拖动组件通常是一个坏主意,您最终会遇到各种奇怪和随机的问题。 相反,您应该专注于传输数据。
因此,在本例中,我将“数据”与“用户界面”分离。 有一个Item
(数据),一个ItemPane
(数据视图),它被放置在一个可滚动的容器中。
当您“拖动” ItemPane
时,首先将其从容器中移除,然后提取并“导出” Item
。 当您放下它时,会创建一个新的ItemPane
并将Item
应用于它
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
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.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class Item {
public final String name;
public final Icon icon;
public Item(String name) {
this.name = name;
icon = UIManager.getIcon("OptionPane." + name + "Icon");
}
}
public class ItemPane extends JPanel {
private Item item;
public ItemPane(Item item) {
this.item = item;
setLayout(new FlowLayout(0, 1, 1));
JLabel icon = new JLabel(item.icon, JLabel.CENTER);
JButton button = new JButton(item.name);
JLabel label = new JLabel(item.name);
JTextField textField = new JTextField(item.name);
add(icon);
add(button);
add(label);
add(textField);
}
public Item getItem() {
return item;
}
}
public class TestPane extends JPanel {
public TestPane() {
JPanel mainPanel = new javax.swing.JPanel();
mainPanel.setLayout(new GridLayout(4, 0));
for (String s : Arrays.asList("error","information","question","warning")) {
ItemPane itemPane = new ItemPane(new Item(s));
add(itemPane);
DragDropManager.INSTANCE.installDrag(itemPane);
mainPanel.add(itemPane);
}
DropHandler dropHandler = new DropHandler();
DropTarget dropTarget = new DropTarget(mainPanel, DnDConstants.ACTION_MOVE, dropHandler, true);
mainPanel.setDropTarget(dropTarget);
setLayout(new BorderLayout());
add(new JScrollPane(mainPanel));
}
public enum DragDropManager {
INSTANCE;
private Map<ItemPane, DragManager> handlers = new HashMap<>(25);
protected void installDrag(ItemPane comp) {
handlers.put(comp, new DragManager(comp));
}
protected void uninstallDrag(Component comp) {
DragManager manager = handlers.remove(comp);
if (manager != null) {
manager.uninstall();
}
}
protected class DragManager {
DragGestureHandler dragGestureHandler;
DragGestureRecognizer dgr;
public DragManager(ItemPane comp) {
dragGestureHandler = new DragGestureHandler(comp);
dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
comp,
DnDConstants.ACTION_MOVE,
dragGestureHandler);
}
public void uninstall() {
dgr.removeDragGestureListener(dragGestureHandler);
dragGestureHandler = null;
dgr = null;
}
}
}
public static class ItemDataFlavor extends DataFlavor {
// This saves me having to make lots of copies of the same thing
public static final ItemDataFlavor SHARED = new ItemDataFlavor();
public ItemDataFlavor() {
super(Item.class, null);
}
}
public static class ItemTransferable implements Transferable {
private DataFlavor[] flavors = new DataFlavor[]{ItemDataFlavor.SHARED};
private Item item;
public ItemTransferable(Item item) {
this.item = item;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
// Okay, for this example, this is over kill, but makes it easier
// to add new flavor support by subclassing
boolean supported = false;
for (DataFlavor mine : getTransferDataFlavors()) {
if (mine.equals(flavor)) {
supported = true;
break;
}
}
return supported;
}
public Item getItem() {
return item;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object data = null;
if (isDataFlavorSupported(flavor)) {
data = getItem();
} else {
throw new UnsupportedFlavorException(flavor);
}
return data;
}
}
public static class DragGestureHandler implements DragGestureListener, DragSourceListener {
private Container parent;
private final ItemPane component;
public DragGestureHandler(ItemPane child) {
this.component = child;
}
public ItemPane getItemPane() {
return component;
}
public Item getItem() {
return component.getItem();
}
public void setParent(Container parent) {
this.parent = parent;
}
public Container getParent() {
return parent;
}
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
// Create our transferable wrapper
Transferable transferable = new ItemTransferable(getItem());
// Start the "drag" process...
DragSource ds = dge.getDragSource();
ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), transferable, this);
// When the drag begins, we need to grab a reference to the
// parent container so we can return it if the drop
// is rejected
Container parent = getItemPane().getParent();
setParent(parent);
// Remove the panel from the parent. If we don't do this, it
// can cause serialization issues. We could over come this
// by allowing the drop target to remove the component, but that's
// an argument for another day
parent.remove(getItemPane());
// Update the display
parent.invalidate();
parent.repaint();
DragDropManager.INSTANCE.uninstallDrag(getItemPane());
}
@Override
public void dragEnter(DragSourceDragEvent dsde) {
}
@Override
public void dragOver(DragSourceDragEvent dsde) {
}
@Override
public void dropActionChanged(DragSourceDragEvent dsde) {
}
@Override
public void dragExit(DragSourceEvent dse) {
}
@Override
public void dragDropEnd(DragSourceDropEvent dsde) {
// If the drop was not sucessful, we need to
// return the component back to it's previous
// parent
if (!dsde.getDropSuccess()) {
getParent().add(getItemPane());
getParent().invalidate();
getParent().repaint();
}
}
}
public class DropHandler implements DropTargetListener {
private JComponent spacer = new JPanel();
public DropHandler() {
spacer.setBackground(Color.RED);
}
@Override
public void dragEnter(DropTargetDragEvent dtde) {
// Determine if can actual process the contents comming in.
// You could try and inspect the transferable as well, but
// There is an issue on the MacOS under some circumstances
// where it does not actually bundle the data until you accept the
// drop.
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
dtde.acceptDrag(DnDConstants.ACTION_MOVE);
} else {
dtde.rejectDrag();
}
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
Point p = dtde.getLocation();
DropTargetContext dtc = dtde.getDropTargetContext();
Container parent = (Container) dtc.getComponent();
Component target = parent.getComponentAt(p);
int insertPoint = Math.max(0, parent.getComponentZOrder(target));
if (spacer.getParent() == null) {
parent.add(spacer, insertPoint);
} else {
parent.setComponentZOrder(spacer, insertPoint);
}
parent.revalidate();
parent.repaint();
Point pic = SwingUtilities.convertPoint(spacer, p, target);
Rectangle bounds = spacer.getBounds();
bounds.setLocation(pic);
((JComponent) parent).scrollRectToVisible(bounds);
}
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
@Override
public void dragExit(DropTargetEvent dte) {
Container parent = (Container) dte.getDropTargetContext().getComponent();
parent.remove(spacer);
parent.revalidate();
parent.repaint();
}
@Override
public void drop(DropTargetDropEvent dtde) {
boolean success = false;
// Basically, we want to unwrap the present...
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
Transferable transferable = dtde.getTransferable();
try {
Object data = transferable.getTransferData(ItemDataFlavor.SHARED);
if (data instanceof Item) {
Item item = (Item) data;
DropTargetContext dtc = dtde.getDropTargetContext();
Component component = dtc.getComponent();
if (component instanceof JComponent) {
Container parent = (Container) component;
Point p = dtde.getLocation();
Component before = parent.getComponentAt(p);
int insertPoint = Math.max(0, parent.getComponentZOrder(before));
parent.remove(spacer);
ItemPane itemPane = new ItemPane(item);
parent.add(itemPane, insertPoint);
parent.revalidate();
parent.repaint();
DragDropManager.INSTANCE.installDrag(itemPane);
success = true;
dtde.acceptDrop(DnDConstants.ACTION_MOVE);
invalidate();
repaint();
} else {
success = false;
dtde.rejectDrop();
}
} else {
success = false;
dtde.rejectDrop();
}
} catch (Exception exp) {
success = false;
dtde.rejectDrop();
exp.printStackTrace();
}
} else {
success = false;
dtde.rejectDrop();
}
dtde.dropComplete(success);
}
}
}
}
@MadProgrammer:很有趣,我刚刚用 Java 8 尝试了你的修改版本,它编译正常,并且可以运行,但我注意到一些问题:
[1] 关闭应用程序后,进程仍在运行,因此我修复了该问题。
[2] 我添加了一个按钮点击监听器,现在它可以 output 一些信息。
[3] 我尝试更改JTextFiled中的一些文本,然后尝试将更改的项目拖放到$ 下,多次拖放后更改被删除,为什么? 它还能记住变化吗? 毕竟可编辑的 JTextFiled 是用于更改文本的,对吧^_^?,但是,如果更改的字段不是 D&D [其他未更改的项目是 D&D]。 然后它似乎记住了这些变化。
所以,总的来说有改进,但如果我们能修复更改的字段并记住文本更改,那么我会非常高兴。 这是我修改后的代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
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.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.addWindowListener( new WindowAdapter()
{
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowClosing(WindowEvent e) { System.exit(0); }
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class Item {
public final String name;
public final Icon icon;
public Item(String name) {
this.name = name;
icon = UIManager.getIcon("OptionPane." + name + "Icon");
}
}
public class ItemPane extends JPanel {
private Item item;
public ItemPane(Item item) {
this.item = item;
setLayout(new FlowLayout(0, 1, 1));
JLabel icon = new JLabel(item.icon, JLabel.CENTER);
JButton button = new JButton(item.name);
button.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if ((e.getModifiers()&InputEvent.BUTTON1_MASK)!=0)
{
// Out("mouseClicked : Left");
System.out.println(item.name);
}
else if ((e.getModifiers()&InputEvent.BUTTON2_MASK)!=0)
{
// Out("mouseClicked : Middle");
}
else if ((e.getModifiers()&InputEvent.BUTTON3_MASK)!=0)
{
// Out("mouseClicked : Right");
}
}
});
JLabel label = new JLabel(item.name);
JTextField textField = new JTextField(item.name);
add(icon);
add(button);
add(label);
add(textField);
}
public Item getItem() {
return item;
}
}
public class TestPane extends JPanel {
public TestPane() {
JPanel mainPanel = new javax.swing.JPanel();
mainPanel.setLayout(new GridLayout(4, 0));
for (String s : Arrays.asList("error", "information", "question", "warning")) {
ItemPane itemPane = new ItemPane(new Item(s));
add(itemPane);
DragDropManager.INSTANCE.installDrag(itemPane);
mainPanel.add(itemPane);
}
DropHandler dropHandler = new DropHandler();
DropTarget dropTarget = new DropTarget(mainPanel, DnDConstants.ACTION_MOVE, dropHandler, true);
mainPanel.setDropTarget(dropTarget);
setLayout(new BorderLayout());
add(new JScrollPane(mainPanel));
}
}
public enum DragDropManager {
INSTANCE;
private Map<ItemPane, DragManager> handlers = new HashMap<>(25);
protected void installDrag(ItemPane comp) {
handlers.put(comp, new DragManager(comp));
}
protected void uninstallDrag(Component comp) {
DragManager manager = handlers.remove(comp);
if (manager != null) {
manager.uninstall();
}
}
protected class DragManager {
DragGestureHandler dragGestureHandler;
DragGestureRecognizer dgr;
public DragManager(ItemPane comp) {
dragGestureHandler = new DragGestureHandler(comp);
dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
comp,
DnDConstants.ACTION_MOVE,
dragGestureHandler);
}
public void uninstall() {
dgr.removeDragGestureListener(dragGestureHandler);
dragGestureHandler = null;
dgr = null;
}
}
}
public static class ItemDataFlavor extends DataFlavor {
// This saves me having to make lots of copies of the same thing
public static final ItemDataFlavor SHARED = new ItemDataFlavor();
public ItemDataFlavor() {
super(Item.class, null);
}
}
public static class ItemTransferable implements Transferable {
private DataFlavor[] flavors = new DataFlavor[]{ItemDataFlavor.SHARED};
private Item item;
public ItemTransferable(Item item) {
this.item = item;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
// Okay, for this example, this is over kill, but makes it easier
// to add new flavor support by subclassing
boolean supported = false;
for (DataFlavor mine : getTransferDataFlavors()) {
if (mine.equals(flavor)) {
supported = true;
break;
}
}
return supported;
}
public Item getItem() {
return item;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object data = null;
if (isDataFlavorSupported(flavor)) {
data = getItem();
} else {
throw new UnsupportedFlavorException(flavor);
}
return data;
}
}
public static class DragGestureHandler implements DragGestureListener, DragSourceListener {
private Container parent;
private final ItemPane component;
public DragGestureHandler(ItemPane child) {
this.component = child;
}
public ItemPane getItemPane() {
return component;
}
public Item getItem() {
return component.getItem();
}
public void setParent(Container parent) {
this.parent = parent;
}
public Container getParent() {
return parent;
}
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
// Create our transferable wrapper
Transferable transferable = new ItemTransferable(getItem());
// Start the "drag" process...
DragSource ds = dge.getDragSource();
ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), transferable, this);
// When the drag begins, we need to grab a reference to the
// parent container so we can return it if the drop
// is rejected
Container parent = getItemPane().getParent();
setParent(parent);
// Remove the panel from the parent. If we don't do this, it
// can cause serialization issues. We could over come this
// by allowing the drop target to remove the component, but that's
// an argument for another day
parent.remove(getItemPane());
// Update the display
parent.invalidate();
parent.repaint();
DragDropManager.INSTANCE.uninstallDrag(getItemPane());
}
@Override
public void dragEnter(DragSourceDragEvent dsde) {
}
@Override
public void dragOver(DragSourceDragEvent dsde) {
}
@Override
public void dropActionChanged(DragSourceDragEvent dsde) {
}
@Override
public void dragExit(DragSourceEvent dse) {
}
@Override
public void dragDropEnd(DragSourceDropEvent dsde) {
// If the drop was not sucessful, we need to
// return the component back to it's previous
// parent
if (!dsde.getDropSuccess()) {
getParent().add(getItemPane());
getParent().invalidate();
getParent().repaint();
}
}
}
public class DropHandler implements DropTargetListener {
private JComponent spacer = new JPanel();
public DropHandler() {
spacer.setBackground(Color.RED);
}
@Override
public void dragEnter(DropTargetDragEvent dtde) {
// Determine if can actual process the contents comming in.
// You could try and inspect the transferable as well, but
// There is an issue on the MacOS under some circumstances
// where it does not actually bundle the data until you accept the
// drop.
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
dtde.acceptDrag(DnDConstants.ACTION_MOVE);
} else {
dtde.rejectDrag();
}
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
Point p = dtde.getLocation();
DropTargetContext dtc = dtde.getDropTargetContext();
Container parent = (Container) dtc.getComponent();
Component target = parent.getComponentAt(p);
int insertPoint = Math.max(0, parent.getComponentZOrder(target));
if (spacer.getParent() == null) {
parent.add(spacer, insertPoint);
} else {
parent.setComponentZOrder(spacer, insertPoint);
}
parent.revalidate();
parent.repaint();
Point pic = SwingUtilities.convertPoint(spacer, p, target);
Rectangle bounds = spacer.getBounds();
bounds.setLocation(pic);
((JComponent) parent).scrollRectToVisible(bounds);
}
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
@Override
public void dragExit(DropTargetEvent dte) {
Container parent = (Container) dte.getDropTargetContext().getComponent();
parent.remove(spacer);
parent.revalidate();
parent.repaint();
}
@Override
public void drop(DropTargetDropEvent dtde) {
boolean success = false;
// Basically, we want to unwrap the present...
if (dtde.isDataFlavorSupported(ItemDataFlavor.SHARED)) {
Transferable transferable = dtde.getTransferable();
try {
Object data = transferable.getTransferData(ItemDataFlavor.SHARED);
if (data instanceof Item) {
Item item = (Item) data;
DropTargetContext dtc = dtde.getDropTargetContext();
Component component = dtc.getComponent();
if (component instanceof JComponent) {
Container parent = (Container) component;
Point p = dtde.getLocation();
Component before = parent.getComponentAt(p);
int insertPoint = Math.max(0, parent.getComponentZOrder(before));
parent.remove(spacer);
ItemPane itemPane = new ItemPane(item);
parent.add(itemPane, insertPoint);
parent.revalidate();
parent.repaint();
DragDropManager.INSTANCE.installDrag(itemPane);
success = true;
dtde.acceptDrop(DnDConstants.ACTION_MOVE);
parent.invalidate();
parent.repaint();
} else {
success = false;
dtde.rejectDrop();
}
} else {
success = false;
dtde.rejectDrop();
}
} catch (Exception exp) {
success = false;
dtde.rejectDrop();
exp.printStackTrace();
}
} else {
success = false;
dtde.rejectDrop();
}
dtde.dropComplete(success);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.