Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Drag and Drop can be a complex beast, not made any easier by the conflicting information that's available. Personally, I like to avoid the Transfer API, but I'm old school like that.</p> <p>The glue to DnD really is the <code>DataFlavor</code>. I prefer to roll my own, makes life a lot easier.</p> <p>In this example, I've used a single <code>TransferHandler</code>, but realistically, you really should have one for dragging and one for dropping, in particular, you should have one for each component you want to drop onto.</p> <p>The main reason for this is, I put a trap in my <code>canImport</code> method to reject it if your dragging over a <code>JList</code>, so you can only drop it on the <code>JLabel</code>, this is a little hack and probably not the best idea.</p> <pre><code>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&lt;ListItem&gt; list; private JLabel label; public TestPane() { list = new JList&lt;ListItem&gt;(); list.setDragEnabled(true); list.setTransferHandler(new ListTransferHandler()); DefaultListModel&lt;ListItem&gt; model = new DefaultListModel&lt;ListItem&gt;(); for (int index = 0; index &lt; 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) &amp;&amp; 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&lt;ListItem&gt; list = (JList&lt;ListItem&gt;) 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(); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload