layer.xml

a netbeans rcp blog

Archive for September, 2010

Auto collapsing JxTaskPane

Posted by Nicklas Löf on September 29, 2010

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("false")) {
            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) &!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.

Posted in SwingX | Tagged: | 1 Comment »

TopComponent Actions in a Flamingo Ribbonband

Posted by Nicklas Löf on September 28, 2010


I recently added Flamingo to my RCP application using the OfficeLAF module. Now I wanted to add all my Topcomponents from the Window menu to a Ribbonband. I will add a blog post later about how to integrate OfficeLAF into a NetBeans RCP application.

I found two ways to do this. One that requires separate Actions to be created for each Topcomponent and the other that doesn’t require any changes to the default TopcomponentActions in layer.xml

To use the later way we can use a Lookup to get all Actions from the Window menu but this gives us also the “Close window” “Reset Windows” actions aswell. But I found out that our actions are of the class AlwaysEnabledAction. Unfortuneatly this class is private so it can’t be used in a instanceof if-statement. My solution to this was to use the name from NBBundle to find the correct Actions by the name.

JRibbonBand band = new JRibbonBand(NbBundle.getMessage(VCA2Ribbon.class, "WINDOWS"),new EmptyResizableIcon(32));
     Collection<? extends Action> actions = Lookups.forPath("Actions/Window").lookupAll(Action.class);
     List<String> myTopComponents = Arrays.asList(getMessageFromBundle("CTL_MyEditorAction"), getMessageFromBundle("CTL_MyPropertiesAction"));

Now I can use the collection to match the name of the actions.

for (Action action : actions) {
if (myTopComponents.contains(ActionUtil.lookupText(action))) {
     band.addCommandButton(new BoundCommandButton(JCommandButton.CommandButtonKind.ACTION_ONLY, ActionUtil.lookupText(action), ActionUtil.lookupDescription(action), ActionUtil.lookupIcon(action), ActionUtil.lookupIcon(action, true), action), RibbonElementPriority.TOP);
}

The other way

The other way I found was to create Actions that extends AbstractAction for each of my TopComponents calling them by the root name of the TopComponent without the TopComponent-part. So if the TopComponent is called MyEditorTopComponent create a class called MyEditorAction.

An empty interface also has to be created that we will use to match the actions against.

public interface MyAction {

}
public class MyEditorAction extends AbstractAction implements MyAction{
  public MyEditorAction() {
     super(NbBundle.getMessage(MyEditorAction.class, "CTL_ MyEditorAction"));
     putValue(SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(MyEditorTopComponent.ICON_PATH, true)));
  }
@Override
  public void actionPerformed(ActionEvent e) {
     TopComponent win = MyEditorTopComponent.findInstance();
     win.open();
     win.requestActive();
  }
}

Edit layer.xml so you only have the file tag left for each topcomponent.

And we are done. Now we need to loop over the actions and add them to the Jribbon.

Collection actions = Utilities.actionsForPath("Actions/Window");
for (Action action : actions) {
   if (action instanceof MyAction){
      band.addCommandButton(new BoundCommandButton(JCommandButton.CommandButtonKind.ACTION_ONLY, ActionUtil.lookupText(action), ActionUtil.lookupDescription(action), ActionUtil.lookupIcon(action), ActionUtil.lookupIcon(action, true), action), RibbonElementPriority.TOP);
    }
}

After launching the application the Ribbon will look like below and when you click the icons the TopComponent will be opened up just like it would when selected in the Window menu.

Posted in Flamingo, Netbeans, OfficeLAF | Tagged: , , | 6 Comments »

Hello world!

Posted by Nicklas Löf on September 28, 2010

Welcome to my new blog about my love and hate to the Netbeans RCP platform. It will contain small tutorials and findings that I’m writing during my journey learning the platform.

I’m absolutely no expert in java or the netbeans platform so by writing down discoveries will hopefully make me understand better.

Posted in Uncategorized | 1 Comment »