Geertjan is a DZone Zone Leader and has posted 466 posts at DZone. You can read more from them at their website. View Full User Profile

Tip: Reusing a Visual Library Popup in the NetBeans Platform Toolbar

08.13.2009
| 7259 views |
  • submit to reddit

A question asked by Martin Has in my blog: "How to migrate visual library PopupMenu actions to the NetBeans Platform toolbar?" I asked Visual Library author David Kaspar this question today and he gave me all the info I needed.

To follow along with the instructions below, download this sample on Kenai:

http://kenai.com/projects/nb-visualanagram/sources/subversion/show/mf_training

We will start with the following section in the "WordGraph" class. This is where a popup menu action is defined. And that's what we'd like to be able to invoke from a menu item in the menu bar AS WELL AS from the same place where it is currently found, i.e., within the scene in the TopComponent:

sc.getActions().addAction(ActionFactory.createPopupMenuAction(new PopupMenuProvider() {
    @Override
    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
        JPopupMenu m = new JPopupMenu();
        m.add(new AbstractAction("Zoom out") {
@Override
            public void actionPerformed(ActionEvent e) {
                sc.setZoomFactor(sc.getZoomFactor() * 0.8);
            }
        });
        return m;
    }
}));

Change the above to the following:

sc.getActions().addAction(ActionFactory.createPopupMenuAction(new PopupMenuProvider() {
    @Override
    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
        Action[] actions = new Action[]{SystemAction.get(ZoomOutAction.class)};
        JPopupMenu m = Utilities.actionsToPopup(actions, sc.getView());
        return m;
    }
}));

Now, in line 4 above, you're referring to an action classcalled "ZoomOutAction" which, in line 5, is turned into a popup menu via a Utilities class provided by the NetBeans Utilities API (org.openide.util.Utilities).

Here's the definition of that action class, i.e., ZoomOutAction. Note that we cannot use an ActionListener class, which would be the ideal approach from 6.7 onwards, since the Utilities.actionsToPopup can only take an Action subclass, hence I've chosen CallableSystemAction:

import org.netbeans.api.visual.widget.Scene;
import org.openide.util.HelpCtx;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;

public class ZoomOutAction extends CallableSystemAction {

    private Scene sc = null;

    public ZoomOutAction() {
        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
            public void run() {
                sc = WindowManager.getDefault().findTopComponent("GraphTopComponent").getLookup().lookup(Scene.class);
            }
        });
    }

    @Override
    public void performAction() {
        sc.setZoomFactor(sc.getZoomFactor() * 0.8);
    }

    @Override
    public String getName() {
        return "Zoom Out";
    }

    @Override
    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }
   
}

Note that in the constructor we're getting the "Scene" object from the context of the GraphTopComponent. If we were to try to get it from the global lookup, we'd have a problem because the GraphTopComponent isn't necessarily active. And it is the active TopComponent that populates the global lookup. Especially since we'll be invoking the action from the menu bar, the GraphTopComponent will possibly not be active (since a different TopComponent could be active when we choose this menu item), hence we need to get the Scene object directly from the GraphTopComponent.

To make the above possible, we need to add the line below to the the GraphTopComponent constructor, so that the Scene object is added to the GraphTopComponent lookup:

associateLookup(Lookups.singleton(sc));

Finally, we need to register the CallableSystemAction in the layer:

<folder name="Menu">
<folder name="File">
<file name="org-netbeans-edu-matfyz09-ZoomOutAction.instance"/>
</folder>
</folder>

And now the same menu item that you invoke from the popup within the TopComponent...

...can also be invoked from a menu item in the main menu bar:

 

AttachmentSize
zoom-out-1.png10.06 KB
zoom-out-2.png2.1 KB
Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Commonwealth Towers replied on Mon, 2014/04/07 - 9:17pm

With full condo facilities, this 99-year leasehold project will offer one- to four-bedroom apartments with unit sizes ranging from 441 sq ft for a one-bedroom to 1,302 sq ft for four-bedders. Buyers can choose from units offering a variety of views such as the city and Southern Ridges. japanese property launches

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.