Combining ListView and ChoiceView
ListView and ChoiceView are two very nice components that can be used to display Node hierarchies. For the RepositoryBrowser Component of my VisualOSGi project I wanted to have a combination of both, a ChoiceView on Top for selecting the Repository and a ListView below for displaying and selecting the individual Bundles. It would be possible to have all the functrionality in a ListView or a BeanTreeView, etc. but I think the combination of a JComboBox and a List is most intuitive.
This is the Node Hierarchy I want to display.
+ Root (AbstractNode)
++ RepositoryNode
+++BundleNode
My first try was using a Palette, but it didn’t play nicely with lazy loading, so I decided to do it myself. The task is now to correctly synchronize the selection between both and still stay in the same Node Hierarchy. My idea was to put the ChoiceView in a JPanel and add a nested JPanel implementing ExplorerManager.Provider with a ListView. The nested Panel then listens for selection changes in the outer Components ExplorerManager to set the root node of it’s own ExplorerManager. So I was very happy to find out that the Rich Client Programming book by Jarda, Tim and Geertjan has an example that is almost exactly what I wanted (Page 186).
I used this code to create a little Component called NestedListView. The View is a JPanel that implements ExplorerManager.Provider to control it’s own Nodes and PropertyChangeListener to listen to changes in the parent. To find the parent, I need to make sure that our component is already added to a parent component, so I’ve putĀ the addNotify method:
@Override
public void addNotify() {
super.addNotify();
parentManager = ExplorerManager.find(this);
if (parentManager != null) {
parentManager.addPropertyChangeListener(this);
}
}
On receiving an interesting PropertyChangeEvent:
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())){
updateRootNode();
}
}
I can update the Node:
public void updateRootNode() {
Node [] n = parentManager.getSelectedNodes();
if (n.length == 0){
explorerManager.setRootContext(new AbstractNode(Children.LEAF));
}
else {
explorerManager.setRootContext(n[0]);
}
}
As the outer component I’ve created another JPanel called ChoiceListView. It contains a ChoiceView to the North.
So now I’ve got a ListView that does exactly what I want:

Since I’ve got a ChildFactory for loading the Nodes the ListView will display some visual feedback while the Nodes are loaded, and the UI isn’t blocked. Another detail is, that I also expose the inner Explorermanager from my ChoiceListView:
public ExplorerManager getChildExplorerManager() {
return choiceListView.getExplorerManager();
}
…because it makes more sense to expose the selected Nodes of the nested Component from the TopComponents Lookup:
associateLookup(ExplorerUtils.createLookup(choiceListView.getChildExplorerManager(), getActionMap()));

Update : As per Geertjan’s request I’m adding the source code of the two classes. The inner class is called Nested ListView and the Outer class is called ChoiceListView. So you can find the two classes here: choicelistview1, nestedlistview1.
Your TopComponent needs to implement ExplorerManager.Provider and define a variable “ExplorerManger explorerManager= new Explorermanager();”. Here’s some Dummy code you can use inside your TopComponents constructor to get them to work:
setLayout(new BorderLayout());
ChoiceListView choiceListView = new ChoiceListView();
add(choiceListView, BorderLayout.CENTER);
// create a three level node hierarchy, like for a palette
Children.Array outer = new Children.Array();
Node[] outerNodes = new Node[3];
for (int j = 0; j < outerNodes.length; j++) {
Children.Array array = new Children.Array();
Node[] children = new Node[3];
for (int i = 0; i < children.length; i++) {
AbstractNode node = new AbstractNode(Children.LEAF);
node.setDisplayName(”Node ” + j+i);
children[i] = node;
}
array.add(children);
AbstractNode choice = new AbstractNode(array);
choice.setDisplayName(”Choice ” + j);
outerNodes[j] = choice;
}
outer.add(outerNodes);
AbstractNode root = new AbstractNode(outer);
root.setDisplayName(”Select something”);
explorerManager.setRootContext(root);
// this exposes the content of the ListView instead of the ChoiceView
associateLookup(ExplorerUtils.createLookup(choiceListView.getChildExplorerManager(), getActionMap()));



Could you provide step by step instructions in your blog for this, using some dummy data? I’ve been trying but failing to follow your instructions (and I don’t have the book at hand).
Comment by Geertjan
— 21. August 2009 @ 22:50
Hi Geertjan,
it’s a very good book, you should get a copy ;-)! I’ve updated the posting, so it contains the two classes and an example.
–Toni
Comment by Toni
— 22. August 2009 @ 09:38
Looking at the code again it probably would make sense to convert it to a real ExplorerView. To do so simply throw out the Exporermanager of the ChoiceListView. This will make the code simpler and you can use it like a regular ExplorerView.
* Update: I implemented this and updated my blog entry. Now ChoiceListView is a regular ExplorerView.
–Toni
Comment by Toni
— 22. August 2009 @ 09:44
…by the way: It would be perfect for displaying Marilyn Monroes Movie hierarchie
Comment by Toni
— 22. August 2009 @ 10:04
[...] days ago I blogged about how to create a new ExplorerView by Combining ListView and ChoiceView. Today I’ll show you how to use this view as a palette for a Visual Library scene. It’s [...]
Pingback by Toni Epple » Adding D&D to ChoiceListView
— 23. August 2009 @ 12:58
[...] for Visual Library: Two days ago I blogged about how to create a new ExplorerView by Combining ListView and ChoiceView. Today I’ll show you how to use this view as a palette for a Visual Library scene. It’s [...]
Pingback by Toni Epple on the Simplest possible Drag&Drop implementation for Visual Library - Technology
— 28. August 2009 @ 19:02
[...] for Visual Library: Two days ago I blogged about how to create a new ExplorerView by Combining ListView and ChoiceView. Today I’ll show you how to use this view as a palette for a Visual Library scene. It’s [...]
Pingback by Poll Result: Java Store/Warehouse Are Finding Early Adopters - Technology
— 28. August 2009 @ 21:00