X

Geertjan's Blog

  • July 1, 2011

A Special Node Indeed

Geertjan Wielenga
Product Manager

In JGridView (Part 2), I showed how to integrate a picture viewer based on the JGrid by Hendrik Ebbers into a NetBeans Platform application.

Today I realized (thanks to Nicklas and Eric from Artificial Solutions in Stockholm) that there was something special about that integration. The key to the integration is this Node:

private class PicNode extends BeanNode {
public PicNode(PicViewerObject key) throws IntrospectionException {
super(key, Children.LEAF, Lookups.singleton(key));
}
}

"Hey,wait a minute," you could be thinking, on seeing the Node above, "what a strange Node. No display name? No icon? Nothing at all?"

Well, not really. The point is that above the business object "PicViewerObject" is added to the Lookup of the Node.

As a result, the ExplorerManager that is responsible for the Node above now gives you access to the underlying business object.

That's really handy, because this lets me construct the model of the JGrid as follows:

public class JGridView extends JScrollPane {
@Override
public void addNotify() {
super.addNotify();
final ExplorerManager em = ExplorerManager.find(this);
if (em != null) {
final JGrid grid = new JGrid();
Node root = em.getRootContext();
final Node[] nodes = root.getChildren().getNodes();
final PicViewerObject[] pics = new PicViewerObject[nodes.length];
for (int i = 0; i < nodes.length; i++) {
Node node = nodes[i];
pics[i] = node.getLookup().lookup(PicViewerObject.class);
}
grid.setModel(new DefaultListModel() {
@Override
public int getSize() {
return pics.length;
}
@Override
public Object getElementAt(int i) {
return pics[i];
}
});
...
...
...

So, I iterate through the Nodes provided by the ExplorerManager, get the underlying business object and add that to the model of the JGrid.

Later, whenever an item in the model is selected, a new Node is created on the fly and set to be the ExplorerManager's selected Node:

grid.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
int selectedIndex = grid.getSelectedIndex();
for (int i = 0; i < nodes.length; i++) {
int picId = pics[i].getId();
if (selectedIndex == picId) {
try {
em.setSelectedNodes(new Node[]{nodes[i]});
} catch (PropertyVetoException ex) {
Exceptions.printStackTrace(ex);
}
}
}
}
});

And that's the key to integrating your own Swing components into the NetBeans Platform.

Join the discussion

Comments ( 3 )
  • Jesse Glick Friday, July 1, 2011

    File a bug in platform/nodes requesting that the single-arg BeanNode constructor include the bean in its lookup. There is no reason you should have to subclass BeanNode just to do that; it is the obvious behavior and ought to be the default.


  • guest Tuesday, July 5, 2011

    And I think (as I said on the training) that there isn't a new node being created here:

    em.setSelectedNodes(new Node[]{nodes[i]});

    it's just creating a single object array that contains the Node created earlier.


  • Geertjan Tuesday, July 5, 2011

    Hi Nicklas, yes, you're right. I see that now, apologies.


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