How to register actions programmatically with NetBeans Platform

"winder" <[email protected]>
Newsgroups gmane.comp.java.netbeans.modules.openide.devel
Message-ID <[email protected]>
I need to register some actions with NetBeans Platform that will show up as Menu items and have configurable Keymap bindings.

Creating individual action classes with annotations works great, but many of my actions invoke simple calls to the same service providers using slightly different arguments. I would like to create them programmatically rather than by creating lots of wrapper classes with lots of annotations.

For example:

Code:

public class JogZPlus extends AbstractAction implements ContextAwareAction {
    JogService jogService;

    public JogZPlus() {
        // Lookup my service class.
        jogService = Lookup.getDefault().lookup(JogService.class);
    }
       
    @Override
    public void actionPerformed(ActionEvent e) {
        // Call the service... repeat 5 more times for +/- X/Y/Z motion...
        // And many more times if I want to add in diagonals.
        jogService.adjustManualLocation(0, 0, 1);
    }

    ...
}




Now, I've figured out how to dynamically add items to the menu (thanks to one of Geertjan's many fantastic tutorials (https://blogs.oracle.com/geertjan/entry/dynamically_creating_menu_items_part)). Then I looked up the Keymap.class object, but haven't figured out how to register the actions with a default keybinding.

Here is how I was able to dynamically create menu actions (this involved creating the menu location in a layer.xml file):

Code:

    private void initActions() {
        SwingUtilities.invokeLater(() -> {
            FileObject menuFolder = FileUtil.getConfigFile("Menu/Machine/Jog");
            try {
                // This way its very obvious what actions are being created.
                registerAction("JogService.xPlus" , menuFolder, 1, 0, 0);
                registerAction("JogService.xMinus", menuFolder,-1, 0, 0);
                registerAction("JogService.yPlus" , menuFolder, 0, 1, 0);
                registerAction("JogService.yMinus", menuFolder, 0,-1, 0);
                registerAction("JogService.zPlus" , menuFolder, 0, 0, 1);
                registerAction("JogService.zMinus", menuFolder, 0, 0,-1);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        });
    }

    private void registerAction(String nameId, FileObject in, int x, int y, int z) throws IOException {
        String name = NbBundle.getMessage(JogService.class, nameId);

        // Create if missing.
        FileObject menu = in.getFileObject(name, "instance");

        // With this approach I noticed that I only need to create the instance the first time.
        if (menu == null) {
            menu = in.createData(name, "instance");

            // Now... how to register this instance with the Keymap?
        }

        AbstractAction action = new JogAction(name, this, x, y, z);
        menu.setAttribute("instanceCreate", action);
        menu.setAttribute("instanceClass", action.getClass().getName());
    }

    protected class JogAction extends AbstractAction {
        JogService js;
        int x,y,z;

        public JogAction(String name, JogService service, int x, int y, int z) {
            super(name);
            js = service;
            this.x = x;
            this.y = y;
            this.z = z;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            js.adjustManualLocation(x, y, z);
        }

        @Override
        public boolean isEnabled() {
            return js.canJog();
        }
    }




Thanks!
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.