将自定义对象从JList拖放到JLabel中

我有一个JList包含自定义对象的ArrayList,我试图创build一个拖放到字段。 我无法理解如何在Transferable中打包和接收对象。

这是关于我已经得到的:

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; public class FlightProjectInterface extends JFrame{ //create GUI Objects private JFrame primaryFrame; private JPanel createFlightPanel; private JPanel aircraftLayout; private JList personsJList, personsOnFlightJList; private JTextField pilotLabel, coPilotLabel, backseat1Label, backseat2Label; public FlightProjectInterface(){ //establish frame super("Create Flight"); setLayout( new FlowLayout()); //aircraftPanel aircraftLayout = new JPanel(); aircraftLayout.setLayout(new GridLayout(2,2)); pilotLabel = new JTextField("Drag Pilot Here"); //build person load list DefaultListModel listModel = new DefaultListModel(); for (Person person : Database.persons) listModel.addElement(person); personsJList = new JList(listModel); personsJList.setVisibleRowCount(5); personsJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); personsJList.setDragEnabled(true); add( new JScrollPane(personsJList) ); aircraftLayout.add(pilotLabel); add(aircraftLayout); }//end constructor } 

澄清:我无法从JList中select对象并从中创buildTransferable。 使用上面的代码,对象的toString表示只是简单地粘贴在文本字段中,所以我无法从丢弃的位置提取对象数据。 我如何“打包”对象本身,并把它放到一个占位符,我可以从GUI引用对象本身?

理想情况下,会有4个字段,每个字段都包含一个可以被删除的对象。 如果被删除,该人将从列表中删除,但是如果被replace,则返回到列表。

拖放可以是一个复杂的野兽,而不是由可用的冲突信息变得更容易。 就我个人而言,我喜欢避免使用Transfer API,但我是那样的老派。

DnD的胶水确实是DataFlavor 。 我更喜欢自己动手,让生活变得更轻松。

在这个例子中,我使用了一个TransferHandler ,但实际上,您应该有一个用于拖放,另一个用于放置,特别是,您应该为每个要拖放的组件添加一个。

这样做的主要原因是,我在canImport方法中放置了一个陷阱,如果您拖动JList ,就会拒绝它,所以您只能将其放在JLabel ,这是一个小问题,可能不是最好的主意。

 import java.awt.BorderLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.io.IOException; import javax.swing.DefaultListModel; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.TransferHandler; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class DnDTransferableTest { public static void main(String[] args) { new DnDTransferableTest(); } public DnDTransferableTest() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } @SuppressWarnings("serial") public class TestPane extends JPanel { private JList<ListItem> list; private JLabel label; public TestPane() { list = new JList<ListItem>(); list.setDragEnabled(true); list.setTransferHandler(new ListTransferHandler()); DefaultListModel<ListItem> model = new DefaultListModel<ListItem>(); for (int index = 0; index < 10; index++) { model.addElement(new ListItem("Item " + index)); } list.setModel(model); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weighty = 1; gbc.weightx = 1; gbc.fill = GridBagConstraints.BOTH; add(new JScrollPane(list), gbc); label = new JLabel("Drag on me..."); gbc.gridx++; gbc.weightx = 1; gbc.fill = GridBagConstraints.NONE; add(label, gbc); label.setTransferHandler(new ListTransferHandler()); } } @SuppressWarnings("serial") public class ListTransferHandler extends TransferHandler { @Override public boolean canImport(TransferSupport support) { return (support.getComponent() instanceof JLabel) && support.isDataFlavorSupported(ListItemTransferable.LIST_ITEM_DATA_FLAVOR); } @Override public boolean importData(TransferSupport support) { boolean accept = false; if (canImport(support)) { try { Transferable t = support.getTransferable(); Object value = t.getTransferData(ListItemTransferable.LIST_ITEM_DATA_FLAVOR); if (value instanceof ListItem) { Component component = support.getComponent(); if (component instanceof JLabel) { ((JLabel)component).setText(((ListItem)value).getText()); accept = true; } } } catch (Exception exp) { exp.printStackTrace(); } } return accept; } @Override public int getSourceActions(JComponent c) { return DnDConstants.ACTION_COPY_OR_MOVE; } @Override protected Transferable createTransferable(JComponent c) { Transferable t = null; if (c instanceof JList) { @SuppressWarnings("unchecked") JList<ListItem> list = (JList<ListItem>) c; Object value = list.getSelectedValue(); if (value instanceof ListItem) { ListItem li = (ListItem) value; t = new ListItemTransferable(li); } } return t; } @Override protected void exportDone(JComponent source, Transferable data, int action) { System.out.println("ExportDone"); // Here you need to decide how to handle the completion of the transfer, // should you remove the item from the list or not... } } public static class ListItemTransferable implements Transferable { public static final DataFlavor LIST_ITEM_DATA_FLAVOR = new DataFlavor(ListItem.class, "java/ListItem"); private ListItem listItem; public ListItemTransferable(ListItem listItem) { this.listItem = listItem; } @Override public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[]{LIST_ITEM_DATA_FLAVOR}; } @Override public boolean isDataFlavorSupported(DataFlavor flavor) { return flavor.equals(LIST_ITEM_DATA_FLAVOR); } @Override public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return listItem; } } public static class ListItem { private String text; public ListItem(String text) { this.text = text; } public String getText() { return text; } @Override public String toString() { return getText(); } } }