september 29, 2010

Auto collapsing JxTaskPane

Auto collapsing JxTaskPane

This post actually doesn't have anything to do with Netbeans RCP but I thought I would share it anyway since it can be used in a Netbeans RCP application.

I added the JXTaskPane component from the SwingX package to my application. One thing that I didn't like in my application was that multiple panes could be open at the same time. I would rather have the possibility to collapse the other ones automatically.

But looking in the javadoc didn't really give any hints that this was a builtin feature into the JXTaskPane so I decided to implement it myself.

To do this is quite easy. First of all we need a collection of the Panes since there is no jxTaskPaneContainer.getPanes() method. It's probably possible to use getComponents and implement a loop that checks if component instanceof JXTaskPane then....  But I preferred to keep my panes in a separate collection instead. In my application that works since the content is static and never changes but for dynamic content the other approach might be a better choice.

So..  lets add a collection of JXTaskPanes as a field. Also add the JXTaskPaneContainer as a field.

private final Collection<JXTaskPane>; taskPanes = new ArrayList<JXTaskPane>(); private final JXTaskPaneContainer jXTaskPaneContainer = new JXTaskPaneContainer();

Then create a method that will take a created pane and add it to both the Collection and the PaneContainer.

private void addPane(JXTaskPane pane) { jXTaskPaneContainer.add(pane); taskPanes.add(pane); }

Now we need a way to get informed that a pane has been uncollapsed. This can be done with the help of listeners. JXTaskPane doesn't have any custom Listeners so we need to use a PropertyChangeListener. Easiest way is to implement one as a private class.

private static class CollapseListener implements PropertyChangeListener { private final MyTopComponent component; private final JXTaskPane pane; public CollapseListener(MyTopComponent component, JXTaskPane pane) { this.component = component; this.pane = pane; } @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("collapsed"); evt.getNewValue().toString().equals(&quot;false&quot;)) { component.collapseAllPanesExceptChoosen(pane); } } }

Now we can see that there is one last method missing. The one that will take care of the actual auto collapsing.

private void collapseAllPanesExceptChoosen(JXTaskPane choosenPane) { for (JXTaskPane jXTaskPane : taskPanes) { if (!jXTaskPane.equals(choosenPane) &amp;!jXTaskPane.isCollapsed()) { jXTaskPane.setCollapsed(true); } } }

And we almost done. We must add the listner to all the panes. Either we can do this in our addPane method or in another method that creates the panes or manually on each pane. It's only one line of code

taskPane1.addPropertyChangeListener(new CollapseListener(this, taskPane1)); taskPane2.addPropertyChangeListener(new CollapseListener(this, taskPane2));

Done!  Now the previous taskpane that was open will be closed automatically when you click on another one.