Archive

Archive for March, 2014

Recipe 13: Customize the menu and the toolbar(s)

March 4, 2014 Leave a comment

Problem

How can I customize the menu and the toolbar(s) of my RCP application?

Solution

Each module contains a layer.xml file which is something like a registry of the module. It contains information about the windows, menus, toolbars, actions etc. of the module. The RCP combines all layer.xml files of all modules to create the final application layout. Without getting into too much detail, you can display layer.xml of  a module by right-clicking on it and selecting: New | Other | Module Development | XML Layer. Then, if you expand the Imporant Files menu you see an XML Layer node which contains two subnodes: <this layer> and <this layer in context>. The first contains the menus, actions etc. of the current module (local registry) while the second is the global registry (of the application).

By right clicking, e.g. on a menu item, you have actions like Delete, Rename, New etc. which you can use to customise the menus according to your needs. Similar case for toolbars, actions etc.

Categories: Toolbar

Recipe 12: How can I disable closing/undocking of a TopComponent?

March 4, 2014 Leave a comment

Problem

All top components contain a tab with a close (x) button. Once the user closes it, the only way to display it is via the Window menu or via Window | Reset Windows. However, if the Window menu has been deleted, then there is no other way to display the top component than restarting the application.

Solution

The close (x) button can be disabled by adding the following command(s) in the constructor of the top component:

putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);

When creating a new TopComponent, you can disable closing it by checking the

  • Closing not allowed
  • Undocking not allowed

checkboxes in the first page of the New Window wizard.

As an aside, if you wish to completely get rid of the tab, then follow the instructions given here. In short add in the TopComponent‘s constructor:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        UIManager.put("EditorTabDisplayerUI", "todo.view.NoTabsTabDisplayerUI");
    }
 }); 

and add the new class NoTabsTabDisplayerUI as mentioned in the aforementioned blog.

Categories: TopComponent

Recipe 11: Why my OutlineView is not refreshed?

March 2, 2014 Leave a comment

Problem

Your outline view needs to be updated from data that are received from the network or when you edit a cell and press ENTER, nothing happens. Or when you add/remove a row the outline view is not updated.

Solution

For the cells to be updated/refreshed, one needs to add a property change listener to the underlying bean that when a property is changed, the node is refreshed, e.g.

public class MyNode extends BeanNode<MyBean> {

   private final transient PropertyChangeListener pcl = new PropertyChangeListener() {

     @Override
     public void propertyChange(final PropertyChangeEvent evt) {
       firePropertySetsChange(null, getPropertySets());
     }
   };

   public MyNode(MyBean bean) throws IntrospectionException {
     super(bean, Children.LEAF, Lookups.singleton(bean));
     bean.addPropertyChangeListener(pcl);
   }
}

and you need to fire a property change in your bean when a property changed.
This will refresh your outline view each time a cell value is changed.
To refresh your outline view when a row is added/removed, you need to modify your ChildFactory accordingly, e.g.

public class MyChildFactory extends ChildFactory<MyBean> {

   private final MyProvider provider;
   private final transient PropertyChangeListener pcl = new PropertyChangeListener() {

     @Override
     public void propertyChange(final PropertyChangeEvent evt) {
       refresh(true);
     }
   };

   public MyChildFactory() {
     provider = Lookup.getDefault().lookup(MyProvider.class);
     provider.addPropertyChangeListener(pcl);
   }

   @Override
   protected boolean createKeys(final List<MyBean> toPopulate) {
     toPopulate.addAll(provider.list());
     return true;
   }
}

where MyProvider is a service provider that popuplates your ChildFactory. Again, you need to fire a property change in your provider when an instance of MyBean is added/removed from it.

Categories: OutlineView

Recipe 10: How to remove a filter that returned no rows from an OutlineView?

March 2, 2014 Leave a comment

Problem

By right-clicking inside an outline view, a popup menu is displayed where you can select the action Show only rows where you can define your criteria depending under which column you clicked. However, if the filter resulted in no rows, how can you display all rows again since the action is displayed only when there are visible rows in the outline view?

Solution

An easy solution is to add a toolbar next to your outline view inside the top component and add the following button:

public class RemoveFilterAction extends AbstractAction {
  /** The outline view to sort. */
  private final OutlineView outlineView;
  /** PropertyChangeListener to set the enabled state. */
  private final PropertyChangeListener pcl = new PropertyChangeListener() {
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
       setEnabled(RemoveFilterAction.this.outlineView.getOutline().getQuickFilterColumn() != -1);
     }
  };

  /**
    *
    * @param view the outline view to remove filter from.
    */
  public RemoveFilterAction(OutlineView view) {
     super(NbBundle.getMessage(RemoveFilterAction.class, "HINT_RemoveFilter"),
           ImageUtilities.loadImageIcon("deleteFilter.png", false));
     this.outlineView = view;
     view.getOutline().addPropertyChangeListener(pcl);
     pcl.propertyChange(null);
     putValue(SHORT_DESCRIPTION, org.openide.util.NbBundle.getMessage(RemoveFilterAction.class, "HINT_RemoveFilter"));
  }

  @Override
  public void actionPerformed(ActionEvent e) {
     outlineView.getOutline().unsetQuickFilter();
     pcl.propertyChange(null);
  }
}

where

HINT_RemoveFilter=Remove the applied filter from view

Whenever a filter is applied to the outline view, the button becomes enabled, and by clicking on it the filter is removed.

Categories: Filter, OutlineView