X
  • Tuesday, April 1, 2014

Dynamically Creating Menu Items (Part 2)

By: Geertjan Wielenga | Product Manager

OK, following on from yesterday, here's the next part. What we want to do is click a button, such as shown below, and, when the button is clicked, cause a new menu item to be added to a predefined menu, in this case the "Shortcuts" menu.

The first step is to define the Shortcuts menu in a layer.xml file:

<folder name="Menu">
    <folder name="Shortcuts"/>
</folder>

Next, we want to populate that folder dynamically, whenever the user clicks the button above. To do that, we need to get hold of the Shortcuts folder within the Menu folder. Then we add in there a new file with ".instance" as the extension, assign our own Action to it, and (as described here, thanks Ernie and the vi/vim project), use the "instanceCreate" and "instanceClass" attributes.

public class SomeTopComponent extends TopComponent {
    private DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    public SomeTopComponent() {
        setDisplayName("Some");
        setLayout(new BorderLayout());
        add(new JButton(new AbstractAction("Add new menu item to shortcuts") {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        final String formatted = formatter.format(System.currentTimeMillis());
                        FileObject menuFolder = FileUtil.getConfigFile("Menu/Shortcuts");
                        try {
                            FileObject newMenu = menuFolder.createData(formatted, "instance");
                            AbstractAction action = new AbstractAction(
                                    "Added at: " + formatted) {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    JOptionPane.showMessageDialog(null, formatted);
                                }
                            };
                            newMenu.setAttribute("instanceCreate", action);
                            newMenu.setAttribute("instanceClass", action.getClass().getName());
                        } catch (IOException ex) {
                            Exceptions.printStackTrace(ex);
                        }
                    }
                });
            }
        }), BorderLayout.NORTH);
    }
}

OK. We now know how to dynamically add a new menu item within a top level menu. But can a top level menu be itself created dynamically too?

That's even simpler:

public class SomeTopComponent extends TopComponent {
    private DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
    public SomeTopComponent() {
        setDisplayName("Some");
        setLayout(new BorderLayout());
        add(new JButton(new AbstractAction("Add new menu to main menubar") {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        final String formatted = formatter.format(System.currentTimeMillis());
                        FileObject menuFolder = FileUtil.getConfigFile("Menu");
                        try {
                            menuFolder.createFolder("Added at: " + formatted);
                        } catch (IOException ex) {
                            Exceptions.printStackTrace(ex);
                        }

                    }
                });
            }
        }), BorderLayout.NORTH);
    }
}

The result:


Join the discussion

Comments ( 3 )
  • guest Monday, June 8, 2015

    Hello,

    thank you for nice tutorial, I am just wondering how I can do localization of custom Action category, i.e., "Shortcuts" in case of declaration via annotations:

    @ActionID(category = "Shortcuts", id = "org.bla.core.DynamicShortcutMenu").


  • markiewb Sunday, March 13, 2016
  • Louis Thursday, June 23, 2016

    Is there a way to rename an existing top level menu?


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services