Drag a Node from a BeanTreeView onto a Node

Let's extend the example from yesterday to support a drop of the Node onto a BeanTreeView instead of our TopComponent. In the end, we'll have two TopComponents, like this:

When you hold down the Ctrl key and drag a Node from the list of boy names, you can drop it onto a name in the list of girl names, which will cause the boy name to be added to the list of girl names:

Do the following:

  1. Take the steps outlined in yesterday's blog entry. That's the starting point for the steps that follow.
  2. In the NodeChildFactory, which defines the list of boy names (shown yesterday), remove the drag() override. Yesterday, we were dragging Customer objects. Today, we want to be dragging the Node instead, which is the default behavior of the drag() method. We want to drag the Node instead of the Customer, because later we will be using org.openide.nodes.NodeTransfer to retrieve a Node from the Transferable.
  3. Next, open the second TopComponent. Yesterday it contained a JLabel, with a text that changed on the drop of the Customer onto the TopComponent. Today, remove the JLabel and replace it with a BeanTreeView, which means you need to implement ExplorerManager.Provider. Also remove the DropTargetListener, because we will be using the BeanTreeView's own DropTargetListener, which delegates to the Node. Create the Node like this in the constructor: 
    em.setRootContext(new AbstractNode(Children.create(new DummyChildFactory(), true)));

    Then define the children of the Node as follows, taking special note of the section in bold below:

    import java.awt.datatransfer.Transferable;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import org.openide.nodes.AbstractNode;
    import org.openide.nodes.ChildFactory;
    import org.openide.nodes.Children;
    import org.openide.nodes.Node;
    import org.openide.nodes.NodeTransfer;
    import org.openide.util.datatransfer.PasteType;
    
    class DummyChildFactory extends ChildFactory<String> {
        
        ArrayList<String> names = new ArrayList<String>();
    
        public DummyChildFactory() {
            names.add( "Jane");
            names.add( "Judy");
            names.add( "Paula");
        }
    
        @Override
        protected boolean createKeys(List<String> list) {
            for (String name : names) {
                list.add(name);
            }
            return true;
        }
    
        @Override
        protected Node createNodeForKey(String name) {
            Node node = new AbstractNode(Children.LEAF){
    
                @Override
                public PasteType getDropType(Transferable t, int arg1, int arg2) {
                    final Node node = NodeTransfer.node(t, arg1);
                    return new PasteType() {
                        @Override
                        public Transferable paste() throws IOException {
                            names.add(node.getDisplayName());
                            refresh(true);
                            return null;
                        }
                    };
                }
            };
    
            node.setDisplayName(name);
            return node;
        }
    
    }

    Optionally, instead of the Node, you can drop a Customer object instead, assuming you've overridden the drag() as explained yesterday (take note of the two lines in bold below, which are the only ones different to the dropping of the Node described above):

    @Override
    public PasteType getDropType(Transferable t, int arg1, int arg2) {
        try {
            final Customer c = (Customer) t.getTransferData(Customer.DATA_FLAVOR);
            //final Node node = NodeTransfer.node(t, arg1);
            return new PasteType() {
                @Override
                public Transferable paste() throws IOException {
                    names.add(c.getName());
                    refresh(true);
                    return null;
                }
            };
        } catch (UnsupportedFlavorException ex) {
            Exceptions.printStackTrace(ex);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        return null;
    }

Make sure to drop onto a girl name, not between them, because in between the Nodes is handled by the root Node, which is the AbstractNode defined in the TopComponent, in this case. So, to support the in between bits, you'd have to also add drop functionality to a custom root Node. I.e., create a new Node that extends AbstractNode and then use that Node as the root of your children.

Thanks to Stan Aubrecht for helping with this scenario.

Comments:

I've just noticed that you finally switched to GTK LAF on Ubuntu. If you like the Default Ubuntu Human theme, but also would like NetBeans to look even cooler, then select: System -> Preferences -> Appearance -> Theme -> Human-Clearlooks

Posted by Laszlo Kishalmi on March 16, 2009 at 09:17 PM PDT #

Honestly, I prefer Metal. I've never understood what's so wrong with it. I only don't use it when I can't be bothered to set the requisite switch in the IDE that enables it.

Posted by Geertjan Wielenga on March 16, 2009 at 09:20 PM PDT #

I have implemented pretty much what you have suggested. I am using a BeanTree View and wanting to just support the moving and copying of nodes within the Tree itself. What I am doing differently is that the data each node contains is actually part of a separate collection so I have to maintain that myself in the paste mehtod. I notice that when getDropType is called that the action value is a large number whenever a move is performed and the correct value when a copy is performed. Second, when a move is performed the icon doesn't change to show that it is allowed to be dropped but always remains as not allowed.

I have gone over and over your tutorials and I can't see that you are doing anything that would enable or disable support for moving so I would assume yours just works so what could I be doing wrong?

Thanks in advance.

Posted by Blaine on March 23, 2009 at 04:32 AM PDT #

[Trackback] One of the challenges I recently undertook was to find a way for my NetBeans application to accept drag-n-drop from outside the application.  From what I have seen, when most programmers think of drag-and-drop it is confined to the context of the vario...

Posted by Dave Rigsby&#039;s Blog on August 26, 2009 at 02:17 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog on August 26, 2009 at 02:19 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog on August 26, 2009 at 02:20 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog on August 26, 2009 at 02:24 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog on August 26, 2009 at 02:26 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog-o-Code on August 26, 2009 at 02:32 PM PDT #

[Trackback] When most programmers think of drag-and-drop, it is usually confined to the context of the various components within the application. For example, dragging a node from a JTree to another JTree, dragging some text to a JTextField and so forth.  I wanted...

Posted by Dave Rigsby&#039;s Blog-o-Code on August 26, 2009 at 02:33 PM PDT #

Dear geertjan,

I searched the whole internet and the netbeans communities to find a way to be able to drag some nodes from palette to explorer's views such IconView or ListView. There is no solution out there. After spending hours on this issue i finally succeeded on that. I wanted you to know that i would be happy to give my solution to you so it will be published as a tutorial on your site. ( I think there are so many people with this problem)

Regards
Sam Sepassi

Posted by guest on October 24, 2011 at 08:17 AM PDT #

Here's where you can publish it: http://netbeans.dzone.com. Let me know if you need help (and write to me at geertjan dot wielenga at oracle dot com).

Posted by Geertjan on October 24, 2011 at 10:00 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
24
25
26
27
28
29
30
   
       
Today