Adding pop-up menus

Unlike the equipment Swing component, the equipment JSF component does not rely on the IlpPopupMenuFactory interface to declare contextual menus. Instead, it is based on the contextualMenu tag defined in the jviews-framework-faces.tld tag library descriptor. This means that pop-up menus in equipment JSF cannot be declared in CSS files.
The contextualMenu tag allows you to define two distinct types of pop-up menu:
  • Static pop-up menus: The menu structure is hard coded in the JSP™ file, it applies to all objects and cannot be changed dynamically.
  • Dynamic pop-up menus: The menu structure is defined by the IlvMenuFactory interface and can be created dynamically where the pop-up was activated
Note
In JViews TGO JSF, the pop-up menu does not trigger any object selection, that is, the object right below the mouse pointer is not automatically included in the selection model.

How to add a static pop-up menu to an equipment JSF component

The static pop-up menu is fully declared within the JSP file, using the following tags:
  • contextualMenu ( jviews-framework-faces.tld library)
  • menu ( jviews-faces.tld library)
  • menuItem ( jviews-faces.tld library)
  • menuSeparator ( jviews-framework-faces.tld library)
The following example illustrates how to declare a static pop-up menu within an equipment JSF component:
    <!-- Declare the Equipment JSF component -->
    <jvtf:equipmentView id="myEquipment" 
                        context="#{contextBean}"
                        style="width:740;height:550" 
                        project="data/default_project.xml">
      <!-- Declare the contextual menu -->
      <jvf:contextualMenu>
        <!-- Declare the root popup menu -->
        <jv:menu label="root">
          <jv:menuItem label="Zoom In" 
                       image="images/zoom.png"
                       onclick="myEquipment.zoomIn()" />
          <jv:menuItem label="Zoom Out" 
                       image="images/unzoom.png"
                       onclick="myEquipment.zoomOut()" />
          <jv:menuSeparator />
          <jv:menuItem label="Fit To Contents" 
                       image="images/zoomfit.png"
                       onclick="myEquipment.showAll()" />
          <jv:menuItem label="Alert!" 
                       image="images/alert.png"
                       onclick="alert('Alert menu item!')" />
        </jv:menu>
      </jvf:contextualMenu>
    </jvtf:equipmentView>
In this example, the contextualMenu tag is declared within the equipment JSF component declaration ( equipmentView tag). It is structured as a root menu ( menu tag) with multiple menu items ( menuItem tags).
The onclick attribute in the menuItem tag is the most important. It defines the JavaScript™ code to be executed when the menu item is selected. See index for details on the available tag attributes.
If you have started the bundled Tomcat web server, the following link will take you to the small sample illustrating how to declare a static pop-up menu: http://localhost:8080/jsf-equipment-step-by-step/faces/example15.jsp .
You will find more information about the sample web application in: <installdir> /samples/faces/jsf-equipment-step-by-step/index.html where <installdir> stands for the directory where Rogue Wave JViews TGO is installed.

How to add and customize a dynamic pop-up menu for an equipment JSF component

Like the static pop-up menu, the dynamic pop-up menu is declared in a JSP page using the contextualMenu tag inside the equipment JSF declaration ( equipmentView tag). However, instead of declaring the menu structure, it declares a menu factory (implementing the IlvMenuFactory interface) that is invoked whenever the pop-up menu is activated. The following example illustrates how the dynamic pop-up menu is declared:

    <head>
      <!-- Specify a CSS file -->
      <link href="data/style.css" rel="stylesheet" type="text/css"/>
    </head>

    <!-- Declares a select interactor, which will be attached to the view -->
    <jvtf:selectInteractor id="select"
                             menuModelId="selectInteractor"
                             invocationContext="IMAGE_SERVLET_CONTEXT" />

    <!-- Declare the Equipment JSF component -->
    <jvtf:equipmentView id="myEquipment" 
                        context="#{contextBean}"
                        interactorId="select" 
                        backgroundColor="#F5F5F5"
                        style="width:740;height:550" 
                        project="data/default_project.xml">
      <!-- Declare the contextual menu with given popup menu factory -->
      <jvf:contextualMenu factory="#{popupMenuFactory}"
                          itemStyleClass="menuItem" 
                          itemHighlightedStyleClass="menuItemHighlighted" 
                          itemDisabledStyleClass="menuItemDisabled" />
    </jvtf:equipmentView>
As shown above, the contextualMenu tag is used within the equipmentView declaration to add a pop-up menu to the equipment JSF component. In addition, the following tag attributes are noteworthy:

The factory tag attribute

This attribute of the contextualMenu tag is bound to a bean implementing the IlvMenuFactory interface, which defines one single method:
  public IlvMenu createMenu(Object graphicComponent, Object selectedObject, 
String menuModelId);
When this method is automatically called, the graphicComponent attribute refers to the underlying graphic view ( IlpGraphView, superclass of IlpEquipmentView). It allows full access to the IlpEquipmentView API, including selection model, controller, and so on.
The selectedObject attribute refers to the representation object ( IlpRepresentationObject) located immediately below the mouse pointer when the pop-up menu was activated, if any. Note that this object may or may not be selected. It is independent of the selection model.
The menuModelId corresponds to the value set in the menuModelId tag attribute of the selectInteractor tag. It allows you to create custom pop-up menus based on the active interactor.
The following IlvMenuFactory example creates a basic pop-up menu:
  public IlvMenu createMenu(Object graphicComponent, 
                            Object selectedObject, 
                            String menuModelId) {
    // Create the root menu
    IlvMenu root = new IlvMenu("Root");

    // Create 3 JavaScript actions
    ActionListener jsAction = new 
JavaScriptActionListener("myEquipment.zoomIn()");
    root.addChild(new IlvMenuItem("Zoom in", jsAction, 
                                  "images/zoom.png", true));

    jsAction = new JavaScriptActionListener("myEquipment.zoomOut());
    root.addChild(new IlvMenuItem("Zoom out", jsAction, 
                                  "images/unzoom.png", true));

    jsAction = new JavaScriptActionListener("alert('Alert menu item!')");
    root.addChild(new IlvMenuItem("Alert!", jsAction, 
                                  "images/alert.png", true));

    return root;
  }
In this example, IlvMenu is the root menu that contains menu items ( IlvMenuItem ). Each menu item has an ActionListener associated with it. In this case, the predefined JavaScriptActionListener class is used to trigger JavaScript code executed on the client when the corresponding menu item is activated. Note that myEquipment in myEquipment.zoomOut() refers to the identifier of the equipmentView JSF component from the previous example. zoomOut() is the JavaScript method that performs zooming out on the client side.

The itemStyleClass , itemHighlightedStyleClass and itemDisabledStyleClass tag attributes

These attributes of the contextualMenu tag are used to customize the look of the pop-up menu. They declare the CSS classes that contain styling definitions for items, highlighted items and disabled items, respectively as follows (from the style.css file):
  .menuItem {
    background: #E5E5E5;
    font-family: sans-serif;
    font-size: 14px;
    font-style: normal;
    color: black;
  }

  .menuItemHighlighted {
    background: #FFE5A5;
    font-style: normal;
    color: black;
  }

  .menuItemDisabled {
    font-style: italic;
    color: #A5A5A5;
  }

The menuModelId tag attribute

This attribute of the selectInteractor tag is used by the menu factory to identify which pop-up menu to create based on the interactor that is currently active.
If you have started the bundled Tomcat web server, the following link will take you to the small sample illustrating how to customize pop-up menus: http://localhost:8080/jsf-equipment-step-by-step/faces/example16.jsp.
You will find more information about the sample web application in: <installdir> /samples/faces/jsf-equipment-step-by-step/index.html where <installdir> stands for the directory where Rogue Wave JViews TGO is installed.

How to trigger server actions from a dynamic pop-up menu of an equipment JSF component

The dynamic pop-up menu can trigger two types of action:
  • client actions: JavaScript actions executed on the client
  • server actions: Java™ actions executed on the server
When building the dynamic menu, the pop-up menu factory ( IlvMenuFactory ) creates a root menu ( IlvMenu ) with menu items ( IlvMenuItem ) and each menu item has an action listener ( ActionListener ) associated with it.
Client actions are defined by the predefined JavaScriptActionListener , which has been described in the previous example.
Server actions, like interactions, can be processed either by the JavaServer™ Faces lifecycle or directly by the image servlet. This is defined by an invocation context that can be either one of the following:
  • JSF_CONTEXT : Processing takes place in the JSF lifecycle (default value)
  • IMAGE_SERVLET_CONTEXT : Processing is performed by the image servlet, bypassing the JSF lifecycle.
Server actions are defined by subclassing the FacesViewActionListener abstract class. The subclass should define the desired invocation context and implement the public void actionPerformed(EventObject event) method. The event parameter is in fact an instance of the ServletActionListener class that has the following convenient methods in its API:
  • getGraphicComponent() : This method returns the underlying view (instance of IlpEquipmentView )
  • getObject() : This method returns the representation object ( IlpRepresentationObject ) located right below the mouse pointer when the pop-up menu was activated)
This allows full access to the IlpEquipmentView API, including selection model, controller, and so on.
The following example shows a basic subclass of FacesViewActionListener :
  public class MyActionListener extends FacesViewActionListener {
    /**
     * Constructor. Sets the invocation context.
     */
    public AddAlarmActionListener() {
      super(IlvDHTMLConstants.IMAGE_SERVLET_CONTEXT);
    }

    /**
     * Access the equipment view and the active object.
     *
     * @param event An instance of ServletActionListener.
     */
    public void actionPerformed(EventObject event) throws Exception {
      ServletActionEvent saEvt = (ServletActionEvent)event;

      // access the equipment view
      IlpEquipmentView view = (IlpEquipmentView)saEvt.getGraphicComponent();

      // access the active object
      IlpObject obj = (IlpObject)saEvt.getObject();

      // implement your action with 'view' and 'obj'
    }
  }
Once the action listener has been defined, it can be used within the pop-up menu factory ( IlvMenuFactory ) as follows:
  public IlvMenu createMenu(Object graphicComponent, Object selectedObject, 
                            String menuModelId) {
    // Create the root menu
    IlvMenu root = new IlvMenu("Root");

    // Create one server action
    ActionListener srvAction = new MyActionListener();
    root.addChild(new IlvMenuItem("My action", srvAction, 
                                  "images/action.png", true));

    return root;
  }
If you have started the bundled Tomcat web server, the following link will take you to the small sample illustrating how to handle server actions: http://localhost:8080/jsf-equipment-step-by-step/faces/example17.jsp.
You will find more information about the sample web application in: <installdir> /samples/faces/jsf-equipment-step-by-step/index.html where <installdir> stands for the directory where Rogue Wave JViews TGO is installed.