Clone wiki

org.openmarkov / Adding an item to a menu

Adding an item to a menu

The item and the action command

If you are creating an item you surely want it to execute an action. If you flip the switch, you expect it to turn on the lights, either with the switch next to the door or the switch above your bed. That is important, you can have ten different switches (items) but the command is one: "turn on, lights".

Normally you have to create the item/s and the action command. This tutorial explains both and how to enable the action command but knowing the difference will help you on the way.

Where to add and when to enable

There are three places to add a menu: the main menu, a toolbar or a contextual menu. And each one enables/disables its action command using setOptionEnabled() in another place:

Where do you want it? Main menu Toolbar Contextual menu
To add the item modify: Main menu class The specific class of the toolbar The specific class of the contextual menu
To enable/disable it modify: The updateOptions methods of MainPanelMenuAssistant class The updateOptions methods of MainPanelMenuAssistant class The specific class of the contextual menu
The one who listens to the item: The actionPerformed method of MainPanelListenerAssistant The actionPerformed method of MainPanelListenerAssistant The actionPerformed method of MainPanelListenerAssistant

Adding

You can easily do every step looking at the code of other menu items in the same menu.

Locate the desired menu class, these are the possible ones as for now (june 2018):

    * MainMenu  

    * StandardToolBar
    * EditionToolBar
    * InferenceToolBar

    * LinkContextualMenu  
    * NodeContextualMenu  
    * NetworkContextualMenu  
    * InstanceContextualMenu  
    * UncertaintyContextualMenu
  1. Create the menu item as an attribute in the menu class.

  2. Create a private getter for it. This getter should initialize the menu item by defining its name, action command and listener, if it is a toolbar, also the icon, tooltip, and other toolbar specifics.

    2.1. For the name create a string attribute in the class that acts as a list of names: MenuItemNames. Use already created items in the menu to place this adding in order to keep it sorted and be consistent with the other modifications, for instance, if I created a "removeNodeAndChildsMenuItem" I would make every modification after the "removeMenuItem" ones.

    2.2. Then create an xml entry for the name in each localized language (That is, in menus_en.xml and menus_es.xml)

    2.3. For the action command create a string attribute in the class that acts as a list of action commands ActionCommands. Again, use already created items to place the entry.

    2.4 [Toolbar specifics] Set the icon path in the icon loader list (the same as names and action commands, remember the localization). Put the icon image in the resorce folder. Set focusable to false. Set the tooltip (and localize it) and program the mouse move listener to reset it.

  3. Create an entry for your item in the protected getter of the menu: getJComponentActionCommand.

Here is a table that summarizes the modifications you should made:

File Modifications
Menu class Declare menu item
Add the item to the menu in initialization methods
Create a private getter that initializes the item
Create an entry in the protected getter
[Toolbar] Set icon, tooltip and mouselistener
Action command list class Create the action command
Name list class Create the name
[Toolbar] Icon loader Create the icon path
XML localization files Localize the name (and toolbar things) in every language

Enabling/disabling

The updateOptions methods

These methods set if each option should be active after the event they describe happen. Some examples are NetworkModified or AllNetworksClosed.

Enabling is different in contextual menus because they are created on the click while the main menu and the toolbars are always there (even if you don't see them). So if an action command is called from both the main menu and a contextual menu, you only need to write your code in the updateOptions methods.

Enabling in main menu and toolbars

Go to MainPanelMenuAssistant and go through the updateOption methods, adding a setOptionEnabled with your action command when necessary. If you need to test for more conditions, add a separate class yourActionValidator that checks them in the constraints folder of the gui module (search for ValidName class or ArcReversalValidator class).

Enabling in contextual menus

Do it in the constructor of the menu class, after the initialize method. First, add a separate class yourActionValidator that checks your conditions in the constraints folder of the gui module (search for ValidName class or ArcReversalValidator class). Then make the constructor of the menu call this test and enable/disable the menu item.

At this point, the menu will show your option and make it available when the constraint is met, but clicking on it will render a message like Not implemented function. ActionPerformed of MainPanelListenerAssistant is listening to your item. Now you could make it run an edit.

Updated