Geertjan's Blog

  • March 19, 2013

Drag Nodes Into Empty NetBeans ListViews

Geertjan Wielenga
Product Manager

I've blogged quite a lot (especially, in the context below, here, back in 2009) about dragging and dropping Nodes into various places. One place I hadn't looked at yet is inspired by the question of the day, provided by Geoffrey Waardenburg in a comment in this blog today: how to drag a Node into an empty ListView. So, rather than dragging a Node onto another Node, the scenario is that you have an empty ListView, i.e., containing no Nodes at all, like this:

Now you want to drag one or more Nodes into that ListView and then, on the drop, display related data there.

The first thing that you need is to have a reference to the JList which is contained within the ListView. Once you have that, you can set it as a drop target.

  1. Create a Custom ListView. Here's the code of my ListView, which exists for no other reason than to expose the underlying and protected JList:
    import javax.swing.JList;
    import org.openide.explorer.view.ListView;
    public class MyListView extends ListView {
    public JList jList;
    protected JList createList() {
    jList = super.createList();
    return jList;
    public JList getjList() {
    return jList;
  2. Listen for Drops on the JList in the ChildFactory. An unorthodox thing to do, yet I challenge anyone to solve this in a different/better way:
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.dnd.DnDConstants;
    import java.awt.dnd.DropTarget;
    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.ArrayList;
    import java.util.List;
    import javax.swing.JList;
    import org.my.domain.Customer;
    import org.openide.awt.StatusDisplayer;
    import org.openide.nodes.AbstractNode;
    import org.openide.nodes.ChildFactory;
    import org.openide.nodes.Children;
    import org.openide.nodes.Node;
    class NameChildFactory extends ChildFactory<Customer> {
    private ArrayList<Customer> names = new ArrayList<Customer>();
    private final JList list;
    public NameChildFactory(JList list) {
    this.list = list;
    MyDropTargetListener dtl = new MyDropTargetListener();
    DropTarget dt = new DropTarget(list, dtl);
    protected boolean createKeys(List<Customer> list) {
    return true;
    protected Node createNodeForKey(final Customer name) {
    Node node = new AbstractNode(Children.LEAF);
    return node;
    public class MyDropTargetListener implements DropTargetListener {
    public void drop(DropTargetDropEvent dtde) {
    if (dtde.isDataFlavorSupported(Customer.DATA_FLAVOR)) {
    try {
    Object transData = dtde.getTransferable().
    if (transData instanceof Customer) {
    Customer c = (Customer) dtde.getTransferable().
    } catch (UnsupportedFlavorException ufe) {
    } catch (IOException ioe) {
    } else {
    public void dragEnter(DropTargetDragEvent dtde) {}
    public void dragExit(DropTargetEvent dtde) {}
    public void dragOver(DropTargetDragEvent dtde) {}
    public void dropActionChanged(DropTargetDragEvent dtde) {}

And that's all you need to do. When a drop takes place on the JList, update the list held by the ChildFactory, and refresh the node hierarchy. (Go here for all the other code in this sample so that you're able to recreate it.)

Join the discussion

Comments ( 4 )
  • Ernest Tuesday, March 19, 2013

    Won't it be practical to just handle this as a DnD action of a node onto an invisible root node of the ListView? Thus, handle this as if it is drops onto RootNode, with the data model hopefully causing the ChildFactory to refresh via listeners. Then, no JList exposure.

    I'll try to write up what I mean a bit more clearly via code ...

  • Geertjan Wednesday, March 20, 2013

    Hi Ernest! I did try that approach, couldn't get it to work. Would indeed be great if you'd try it and report back here with the results.

  • Ernest Thursday, March 21, 2013

    Hi Geertjan! Sure, no problem - this is more of a back-of-the-envelope approach - I'll actually try it and let you know how it goes.

  • Justin Smith Wednesday, September 18, 2013

    Thanks for the tip, again, you saved me some head scratching. Now to enable drag reordering of the nodes in the listview.

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.