Previous Next Contents Generated Index Home


Chapter 17

Advanced Console Customization




This section describes:


General Guidelines

This section includes guidelines as they apply to Static and Dynamic Menus and other general information. These general guidelines also apply to Cell Editors and the Configurable Details Window Interface. Specific requirements and exceptions are listed in the individual sections.


Note - If the user application crashes due to a runtime exception, the console will crash as well.

Exiting Applications Launched from Static and Dynamic Menus

Do not use calls to System.exit() to exit the program. If you do, the entire console window will exit, as well as the integrated package. To exit, make the following calls for the appropriate frames:


Launching a Java Program from Multiple Places in Modules


Note - This section does not apply to "Configurable Details Window Interface."

If it is necessary for the Java program to be aware of where it was launched, then specify a unique argument for each of the following consoleHints:


Note - Note that args can be used to allow different places in the program to specify the same Java file with different arguments to let the Java program know it was called from a different place. For examples of how to define args, refer to the following sections: "To Add Additional Popup Menu Options at the Module or Managed Object Level", "To Add Menu Choices At the Table Level", "To Specify New Dynamic Menu choice(s) Over a Table Cell", "To Specify New Dynamic Menu Choice(s) Over a Table Column Header", "To Specify a Custom Cell Editor".

General Integration Guidelines

The following are general integration guidelines for both static and dynamic menus.


Static Menus

Static Menus provides a method for customizing popup menus in the Browser tab accessed from the Host Details window.

When a user right clicks the mouse over an object in a module, the Sun Management Center displays a popup menu. Developers can add their own choices to the menu at the following places:


Customizing Static Popup Menus

Developers specify the new menu options and associated launch commands in the Module Definition (-d.x) file and specify the Java class to be invoked when the new menu items are selected. This interface is called "Static" because the menu choices are hardcoded in the Module Definition (-d.x) file. In addition, developers may localize the menu items labels and use the provided SMHelpBrowser class to provide help for any new menu items.

The Java program that is invoked when the new menu items are selected must be placed in the following directory: /<Sun_Management_Center_installation_directory>/SUNWsymon/apps/classes.

The Java program is launched with the necessary contextual information so it can determine which object the mouse was over when the program was launched. For example, a menu choice could be added over a table. If a user brings the popup menu over a particular cell in the table and launches the Java program, the program can determine its cell value.

To define additional commands, the consoleHint:commands list indexes the set of available commands. The consoleHint:commandLabel(cmd) and consoleHint:commandSpec(cmd) define each command's information.


 

To Add Additional Popup Menu Options at the Module or Managed Object Level

   Add the following statements to the module definition file (this example adds two additional menu choices):

consoleHint:commands = myapp1 myapp2
consoleHint:commandLabel(myapp1) = My First Application
consoleHint:commandSpec(myapp1) = launchApp acmecorp.MyApp arg1 arg2
consoleHint:commandLabel(myapp2) = My Second Application
consoleHint:commandSpec(myapp2) = launchApp acemecorp.SecondApp

_
  Each command launches the custom application specified by its consoleHint:commandSpec() property. The arguments (arg1 arg2 ...) are passed to the application. These statements are placed in the agent file, for example acmemodule-d.x. When this module is subsequently loaded, two new menu items "My First Application" and "My Second Application" appear in the popup menu.

Note - The particular location at which the popup menu choices are included in the Module Definition (-d.x) file determines where the menu choices will appear in the module.

 

To Add Menu Choices At the Table Level

   Include these statements for a table definition in the module file.

consoleHint:tableCommands = myapp
consoleHint:commandLabel(myapp) = My Application
consoleHint:commandSpec(myapp) = launchApp acmecorp.MyApp arg1 arg2

_

These lines are similar to the lines in the previous example, except that consoleHint:tableCommands is used instead of consoleHint:commands. Once added, the menu item "My Application" will appear in the popup menu.


Integration Guidelines and Notes for Static Menus

This section provides information and guidelines for performing the integration.

The following guidelines are applicable for the SMModApp or SMModAppAdapter.


SMHelpBrowser

A standard Help class is provided to allow user-specific help text to be displayed using the Sun Management Center help system. You can invoke a Help class from a popup menu.


 

To Invoke a Help Class

   Include the following lines inside the module file:

consoleHint:commands = myhelp
consoleHint:commandLabel(myhelp) = My Help
consoleHint:commandSpec(myhelp) = launchApp\ 
com.sun.symon.apps.generic.help.SMHelpBrowser myhelpkey

_

where

Once done, the menu item, "My Help" appears in the popup menu. When this menu item is selected, the Sun Management Center help system will display the user-specified help text.


 

To Integrate the Online Help Mapping Key

In order to use a help key, integrate a mapping from the key to the HTML online help for the application into Sun Management Center.

   Run one of the following commands from the post-install and pre-remove scripts of the server package for the application that you want to integrate:

es-chelp -a key file
es-chelp -d key

_

where


Note - The actual HTML help file for your application must be installed on the Sun Management Center help server.

For example:

es-chelp -a acmehelp ACME_module_help.html
es-chelp -d acmehelp 


Note - For more information on the help key, refer to "Help Key Usage".

Troubleshooting for Static Menus

Sun Management Center errors or debugging messages at the console level.


Console Message Exceptions


Strange Behavior of Integrated Program if Invoked Multiple Times

If the integrated program acts strangely when it is invoked multiple times, you will see the following behavior:

The solution is to only make sure that no classes or variables are defined as static in the integrated program.


New Menu Choices are Not Visible for Static Menus

If the new menu choice is not visible over the expected node, check the module-d.x file for the following:


Example: staticmenu-version01-d.x

CODE  EXAMPLE  17-1 staticmenu-version01-d.x  
#Copyright 05/10/99 Sun Microsystems, Inc. All Rights Reserved.
#pragma ident  "@(#)staticmenu-version01-d.x	1.3 99/05/10 Sun Microsystems"

[ use MANAGED-MODULE ]
[ requires template staticmenu-version01-models-d ]

#
# Tell that the following package is needed.
#

[ load staticmenu-version01-m.x ]

_services = { [ use SERVICE ]
        sh = {
                command = "pipe://localhost//bin/sh;transport=shell"
                max = 1
        }
}

refreshService  = _internal

StaticMenuManagedObject = { [ use templates.staticmenu-version01-models-\ 
d.StaticMenuManagedObject ]
        type = active
        initInterval = 1
        refreshService = _services.sh
        refreshCommand = staticmenu-version01.sh
        refreshInterval = 3600

        # The following consoleHint adds the Context2 menu choice to the table.
        #
        consoleHint:commands = Context2

        # Menu option = "Managed Object Context Example"
        #
        # The following two consoleHints specify the commandLabel (text label)
        # and commandSpec (Java launch command) for the Context2 menu choice.
        # Note that the program SMContextExample is called and is passed one
        # argument ("Managed Object Level").
        # 
        consoleHint:commandLabel(Context2) = Managed Object Context Example
        consoleHint:commandSpec(Context2)  = launchApp SMContextExample "Managed\ 
Object Level"

        StaticMenuTable = {
                StaticMenuEntry = {

 # The following consoleHint adds the Context3 menu choice to the table.
                        #
 consoleHint:tableCommands = Context3

                        # Menu option = "Table Context Example"
                        #
 # The following two consoleHints specify the commandLabel (text label)
 # and commandSpec (Java launch command) for the Context3 menu choice.
 # Note that the program SMContextExample is called and is passed one
                        # argument ("Table Level").
                        # 
                        consoleHint:commandLabel(Context3) = Table Context Example
                        consoleHint:commandSpec(Context3)  = launchApp\ 
SMContextExample "Table Level"
                }
        }
}

# The following consoleHint adds Hello and Context1 menu choices to the module.
#
consoleHint:commands = Hello Context1

# Menu option = "StaticMenu Example!"
#
# The following two consoleHints specify the commandLabel (text label) and
# commandSpec (Java launch command) for the Hello menu choice.
# Note that the program SMHello is called and is passed no arguments.
# 
consoleHint:commandLabel(Hello) = Static Menu Example!
consoleHint:commandSpec(Hello)  = launchApp SMHello

# Menu option = "Module Context Example"
#
# The following two consoleHints specify the commandLabel (text label) and
# commandSpec (Java launch command) for the Context1 menu choice.
# Note that the program SMContextExample is called and is passed one
# argument ("Module Level").
# 
consoleHint:commandLabel(Context1) = Module Context Example
consoleHint:commandSpec(Context1)  = launchApp SMContextExample "Module Level"


Example: SMHello.java

SMHello.java shows how to launch a program from Sun Management Center. The launched program does not interact with Sun Management Center in any other way.

CODE  EXAMPLE  17-2 SMHello.java  
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class SMHello implements ActionListener {

    JFrame frame;
    JPanel panel;

    // Constructor
    //
    public SMHello() {
        frame = new JFrame("Hello World");
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
    }

    // init - Build GUI and display.
    //
    public void init() {
        JButton button = new JButton("Close");
        panel.add(button, BorderLayout.SOUTH);
        button.addActionListener(this);

        panel.add(new JLabel("Hello World from Sun Management 
Center!"),
           BorderLayout.NORTH);
        frame.getContentPane().add("Center", panel);
        frame.pack();
        frame.setVisible(true);
    }

    // actionPerformed - Exit program when Quit button is pressed.
    //
    public void actionPerformed(ActionEvent e) {
        frame.setVisible(false);
        frame.dispose();
    }

    // main - Program entry point.
    //
    public static void main(String argv[]) {
 
        // Note that a call to the System.exit() method is not
        // a valid way to exit programs that are integrated with
        // Sun Management Center.  This is the preferred method.
        //
        SMHello helloPanel = new SMHello();
        helloPanel.init();
    }
}


Example: SMContextExample.java

SMContextExample.java shows how to display contexual information in the launched program. The program shows the table cell value that the user's mouse was hovering over when they launched the application.

CODE  EXAMPLE  17-3 SMContextExample.java  
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.symon.base.server.types.*;
import com.sun.symon.base.client.console.*;
import com.sun.symon.base.client.*;

public class SMContextExample implements ActionListener, SMModApp 
{

    JFrame           frame;
    JPanel           panel;

    SMRawDataRequest handle;
    String           hostName;
    String           topologyName;
    SMUrlContext     urlName;
    String[]         args;
    int              portNo;

    // Constructor
    //
    public SMContextExample() {
        frame = new JFrame("Context Example");
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
    }

    // setAgentHost - Sets the agent host name.
    //
    public void setAgentHost(String hostInput) {
        hostName = hostInput;
    }

    // setAgentName - Sets the topology node name.
    //
    public void setAgentName(String nameInput) {
        topologyName = nameInput;
    }

    // setAgentPort - Sets the agent port number.
    //
    public void setAgentPort(int portInput) {
        portNo = portInput;
    }

    // setRawDataRequestHandle - Sets the client API handle.
    //
    public void setRawDataRequestHandle(SMRawDataRequest\ 
handleInput) {
        handle = handleInput;
    }

    // setUrlContext - Sets the object URL.
    //
    public void setUrlContext(SMUrlContext urlInput) {
        urlName = urlInput;
    }
 
    // setArguments - Allows arguments specified in the launchApp
    //                command to be passed to the application.
    //
    public void setArguments(String[] argsInput) {
        args = argsInput;
    }

    // init - This is an initialization method for third party
    //        applications that integrate into Sun Management
    //        Center.  It gets called after all the set methods
    //        in the SMModApp interface get called.
    //
    public void init() {

        JPanel gridPanel;
        gridPanel = new JPanel();

        JButton button = new JButton("Close");
        button.addActionListener(this);
        panel.add(button, BorderLayout.SOUTH);

        try
        {
            // The gridPanel will have 2 rows for the host name
            // and topology name.  An additional row for each value
            // in the args Array (in this example this value is 1).
            //
            int numRows = 2 + args.length;

            // If the user launched this application from a
            // table, then the 1st argument to this script
            // will be the string "Table Level".  In this case
            // this program will retrieve the cell value
            // associated with the cell the mouse was pointing.
            //
            // Must convert urlName variable into the "request"
            // array of Strings, so we can call the getURLValue
            // clientAPI method.  This returns the value of the
            // cell into the "urlValue" variable.
            //
            String [] request = new String[1];
            StObject [][] urlValue = null;
 
            if (args[0].compareTo("Table Level") == 0) {

                String nodeUrl = "";

                try {

                    nodeUrl = SMRawDataRequest.createURL(
                        urlName.getHost(), urlName.getAgentPort(),
                        urlName.getModuleId(), urlName.getInstance(),
                        urlName.getManagedObject(), 
urlName.getProperty(),
                        urlName.getPropertyType(), "",
                        urlName.getPropertyInstance());

                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                request[0]        = nodeUrl;
                urlValue          = handle.getURLValue(request);
  
                // Add 1 row in the gridPanel for the value in
                // the cell.
                //
                numRows++;
            }
  
            gridPanel.setLayout(new GridLayout(numRows, 2, 3, 3));
            gridPanel.add(new JLabel("Host name:"));
            gridPanel.add(new JLabel(hostName));

            gridPanel.add(new JLabel("Topology name:"));
            gridPanel.add(new JLabel(topologyName));

            // Display list of arguments.
            //
            for (int i = 0; i < args.length; i++)
            {
                gridPanel.add(new JLabel("Argument:"));
                gridPanel.add(new JLabel(args[i]));
            }

            // If this program was launched from a table, we
            // retrieved the cell value above.  Now display
            // that value.
            //
            if (args[0].compareTo("Table Level") == 0)
            {
                gridPanel.add(new JLabel("Value:"));
                gridPanel.add(new JLabel(urlValue[0][0].toString()));
            }
        }

        // The getURLValue() method throws an exception.  We will
        // catch it here and display the error message to the
        // gridPanel.
        //
        catch (Exception e)
        {
            gridPanel.setLayout(new GridLayout(1, 2, 3, 3));
            gridPanel.add(new JLabel("Exception:"));
            gridPanel.add(new JLabel(e.getMessage()));
        }
            
        panel.add(gridPanel, BorderLayout.NORTH);

        frame.getContentPane().add("Center", panel);
        frame.pack();
        frame.setVisible(true);
    }

    // actionPerformed - Exit program when Close button is pressed.
    //
    public void actionPerformed(ActionEvent e)
    {

        // Note that a call to the System.exit() method is not
        // a valid way to exit programs that are integrated with
        // Sun Management Center.  This is the preferred method.
        //
        frame.setVisible(false);
        frame.dispose();
    }
}


Dynamic Menus

Dynamic Menus provide a method for customizing popup menus in the Browser tab accessed from the Host Details window.

When a user right clicks the mouse over an object in a module, the Sun Management Center displays a popup menu. Developers can add their own choices to the menu at the following places:


Customizing Dynamic Popup Menus

Developers specify a Java class in the Module Definition (-d.x) file, which is invoked to build the new menu items. This interface is called "dynamic" because the menu choices are built dynamically at run time. Developers supply ActionListeners in the Java code, which get launched when a new menu item is selected. In addition, developers can localize the menu items labels.

The Java program that is invoked when the new menu items are selected must be placed in the following directory:

/<Sun_Management_Center_installation_directory>/SUNWsymon/apps/classes

The Java program is launched with the necessary contextual information so it can determine which object the mouse was over when the program was launched. For example, a menu choice can be added over a table. If you bring up the popup menu over a particular cell in the table and launch the Java program, the program can determine its cell value.


 

To Specify New Dynamic Menu choice(s) Over a Table Cell

   Implement the following consoleHint command for the table object in the module definition (-d.x) file:

consoleHint:tableMenuGenerator = javaClass [ args ]

_
 

To Specify New Dynamic Menu Choice(s) Over a Table Column Header

   Implement the following consoleHint for the table column object in the module definition (-d.x) file:

consoleHint:columnHeaderMenuGenerator = javaClass [ args ]

_
 

To Test Popup Menus and See the Changes


Note - The following procedure only applies if you change the module files.
  1. Exit any Sun Management Center Host Detail screen.
  2. Restart the Sun Management Center agent.
  3. Bring back up the Sun Management Center host detail screen.

You will see the changes that were added to the module definition (-d.x) file.


Note - It is necessary to stop and restart the console after making any changes to the Java code that is placed in the /opt/SUNWsymon/apps/classes directory.

Rules for Java Implementation for Dynamic Popup Menus

The java class specified in either the tableMenuGenerator or the columnHeaderMenuGenerator consoleHint must either implement:

com.sun.symon.base.client.console.SMMenuGenerator

or, extend:

com.sun.symon.base.client.console.SMMenuGeneratorAdapter


Internationalization for Dynamic Popup Menus

For information on how you can internationalize the menu choices displayed in the popup menu, refer to Chapter 19 and Chapter 20.

For example, you can enter the following in the Java implementation:

import com.sun.sytmon.base.utility.UcInternationalizer
[ ... ]
String menuChoice =
UcInternationalizer.translateKey("myPath.myResourceBundle:myMenuKey");


Troubleshooting (Dynamic Popup Menus)

The following sections provides solutions to some of the common problems.

To view errors or debugging messages, select the: "File -> Sun Management Center-Console Messages..." menu choice from the main Sun Management Center screen.

This section includes common errors and their solutions.


Console Message Exceptions

If the console message includes the following exception:

java.lang.IllegalAccessException at java.lang.Class.newInstance0(Native Method)

Make sure that the constructor of class being launched is public.


Strange Behavior of Integrated Program when Invoked Multiple Times

If the integrated program acts strangely when it is invoked multiple times, you will see the following behavior:


New Menu Choices Are Not Visible for Dynamic Popup Menus

  1. Check the module realization (-d.x) File for the following:
  2. Make sure that the consoleHints are defined within the proper section of the module realization (-d.x) file.

Note - For more information on this topic, also refer to "New Menu Choices are Not Visible for Static Menus".

Example: Dynamic Menu

CODE  EXAMPLE  17-4 dynamicmenu-version01-d.x  
#Copyright 05/10/99 Sun Microsystems, Inc. All Rights Reserved.
#pragma ident  "@(#)dynamicmenu-version01-d.x	1.3 99/05/10 Sun Microsystems"

[ use MANAGED-MODULE ]
[ requires template dynamicmenu-version01-models-d ]

#
# Tell that the following package is needed.
#

[ load dynamicmenu-version01-m.x ]

_services = { [ use SERVICE ]
        sh = {
                command = "pipe://localhost//bin/sh;transport=shell"
                max = 1
        }
}

refreshService  = _internal

# EditCellManagedObject
#
# Displays examples of the various cell editors.
#
EditCellManagedObject = { [ use templates.dynamicmenu-version01-models-\ 
d.EditCellManagedObject ]

        # Text Editor
        #
        EditCellTblCellText = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Integer Editor
        #
        EditCellTblCellInt = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Floating Point Number Editor
        #
        EditCellTblCellFloat = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Checkbox (Boolean) Editor
        #
        EditCellTblCellBool = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor =\ 
com.sun.symon.base.client.console.SMTblBooleanEditor
        }

        # Combo Box Editor
        #
        EditCellTblCellCombo = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor =\ 
com.sun.symon.base.client.console.SMTblComboBoxEditor
                consoleHint:optionList       = entry1 entry2 entry3
        }

        # Custom Editor - uses SMCustomCellEdit class provided with this
        #                 example.  Input must start with the letter A.
        #
        EditCellTblCellCustom = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor = SMCustomCellEdit
        }
}

# DynamicMenuManagedObject
# 
# Displays examples of the various dynamic menus.
#
DynamicMenuManagedObject = { [ use templates.dynamicmenu-version01-models-\ 
d.DynamicMenuManagedObject ]
        DynamicMenuTable = {
                type            = active
                initInterval    = 1
                refreshService  = _services.sh
                refreshCommand  = dynamicmenu-version01.sh
                refreshInterval = 3600

                DynamicMenuEntry = {

                        # Table dynamic menu example.
                        #
                        consoleHint:tableMenuGenerator = SMDynamicMenu \ 
"arg one" "arg two"

                        DynamicMenuIndex = { [ use STRING MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = \ 
SMDynamicMenu "arg one" "arg two"
                        }
                        DynamicMenuTotalSize = { [ use INTHILO MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = SMDynamicMenu
                        }
                        DynamicMenuUsed = { [ use INTHILO MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = SMDynamicMenu
                        }
                        DynamicMenuAvailable = { [ use INTHILO MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = SMDynamicMenu
                        }
                        DynamicMenuCapacity = { [ use STRING MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = SMDynamicMenu
                        }
                        DynamicMenuMounted = { [ use STRING MANAGED-PROPERTY ]

                                # Column Header dynamic menu example.
                                #
                                consoleHint:columnHeaderMenuGenerator = SMDynamicMenu
                        }
                }
        }
}


Dynamic Menu Java Code

CODE  EXAMPLE  17-5 SMDynamicMenu.java  
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import com.sun.symon.base.client.console.SMMenuGenerator;
import com.sun.symon.base.client.console.SMContextPopupItem;
import com.sun.symon.base.client.console.SMContextPopupEvent;
import com.sun.symon.base.client.console.SMTblSelectionInfo;

import javax.swing.JSeparator;
import javax.swing.JMenuItem;

import java.awt.Point;

// SMDynamicMenu
//
// A definition of a dynamic menu.
//
public class SMDynamicMenu implements SMMenuGenerator {

    private String[] args;

    // It is recommended to implement any needed ActionListeners in
    // a seperate class (like SMCustomPopup in this example).  Note that
    // the class that implements SMMenuGenerator is only instantiated 
    // once for each menu, and note that the getMenuItems method is 
    // called each time the menu must be displayed.  Implementing the
    // ActionListeners in a separate class reduces the possibility
    // that there will be conflicts if multiple menu choices are
    // running at the same time.
    //
    private SMCustomPopup customPopup;

    // init - init the class, if necessary.
    //
    public void init(String[] argsIn) {
       args = argsIn;
    }

    // getMenuItems - This method builds the menu choices that will be
    //                made available for the popup.
    //
    public SMContextPopupItem[] getMenuItems(SMContextPopupEvent ev) {

        // The SMCustomPopup class implements the ActionListener for this
        // example.
        //
        customPopup   = new SMCustomPopup(args, ev);

        SMContextPopupItem[] items = new SMContextPopupItem[5];

        int j=1;
        for (int i=0; i < 5; i++) {

            if (i == 3) {

                // Add a seperator at this position.
                //
                items[i] = new SMContextPopupItem(new JSeparator());

            } else {

                JMenuItem menuItem = new JMenuItem("Choice " +
                    String.valueOf(j));

                j++;

                // It is necessary to add ActionListeners for each menu
                // choice in order for an action to be performed when the 
                // menu choice is selected.
                //
                menuItem.addActionListener(customPopup);

                items[i] = new SMContextPopupItem(menuItem);

            }
        }
         
        return items;
    }
}

// SMCustomPopup
//
// The class that implements the ActionListener for this example.
//
class SMCustomPopup implements ActionListener {

    private SMContextPopupEvent popupEvent;
    private JFrame              frame;
    private String[]            args;

    // Constructor
    //
    public SMCustomPopup(String[] argsIn, SMContextPopupEvent pe) {

        // Keep track of the popupevent information.
        //
        args       = argsIn;
        popupEvent = pe;
    }

    // actionPerformed - this method is called when the user selects 
    //                   the menu choice(s) associated with this class.
    //
    public void actionPerformed(ActionEvent e) {

        // This example displays a popup that shows the contextual 
        // information about where the user brought up the pop-up
        // menu.
        //
        JMenuItem source        = (JMenuItem)e.getSource();
        JPanel    panel         = new JPanel();
        JPanel    gridPanel     = new JPanel();
        JLabel    selType       = new JLabel();
        int       column        = popupEvent.getColumn();
        int       rows[]        = null;
        int       row           = popupEvent.getRow();

        frame = new JFrame("Dynamic Menu Example");

        int gridRows = 9;

        if (args != null) {
            gridRows += args.length;
        }

        // Check to see if a row, column, or cell is selected.  If so,
        // then display information about the selection.  Keep track of
        // the number of rows in the gridPanel needed for each type of
        // selection.
        //
        if (popupEvent.getCurrentSelectionInfo() == null) {

            selType.setText("No Selection");
        }
        else {

            int selectionType =
                popupEvent.getCurrentSelectionInfo().getSelectionType();

            if (selectionType == SMTblSelectionInfo.CELL_SELECTION) {

                selType.setText("Cell Selection");
                gridRows += 2;
            }
            else if (selectionType == SMTblSelectionInfo.COLUMN_SELECTION) {

                selType.setText("Column Selection");
                gridRows += 1;
            }
            else if (selectionType == SMTblSelectionInfo.ROW_SELECTION) {

                selType.setText("Row Selection");

                rows = popupEvent.getCurrentSelectionInfo().getSelectedRows();

                if (rows == null) {
                    // To print "N/A" message.
                    //
                    gridRows += 1;
                }
                else {
                    gridRows += rows.length;
                }
            }
        }

        panel.setLayout(new BorderLayout());
        gridPanel.setLayout(new GridLayout(gridRows, 2, 3, 3));

        // Display information about where the user brought up the menu.
        //
        if (row == -1) {
            gridPanel.add(new JLabel("User Clicked On"));
            gridPanel.add(new JLabel("Column Header"));
        }
        else {
            gridPanel.add(new JLabel("User Clicked On"));
            gridPanel.add(new JLabel("Table Cell"));
        }

        gridPanel.add(new JLabel("Menu Choice"));
        gridPanel.add(new JLabel(source.getText()));

        if (args != null) {
            for (int i=0; i < args.length; i++) {
                gridPanel.add(new JLabel("Argument # " +
                    String.valueOf(i + 1)));
                gridPanel.add(new JLabel(args[i]));
            }
        }

        // Display information about the agent machine.
        //
        gridPanel.add(new JLabel("Agent Host"));
        gridPanel.add(new JLabel(
           popupEvent.getObjectDetailContext().getHost()));

        gridPanel.add(new JLabel("Agent Node Name"));
        gridPanel.add(new JLabel(
           popupEvent.getObjectDetailContext().getNodeName()));

        // Display information about what is selected, or that nothing is
        // selected.
        //
        gridPanel.add(new JLabel("SelectionType"));
        gridPanel.add(selType);

        if (popupEvent.getCurrentSelectionInfo() != null) {

            int selectionType =
                popupEvent.getCurrentSelectionInfo().getSelectionType();

            if (selectionType == SMTblSelectionInfo.COLUMN_SELECTION ||
                selectionType == SMTblSelectionInfo.CELL_SELECTION) {

                gridPanel.add(new JLabel("Selected Column"));
                gridPanel.add(new JLabel(String.valueOf(
                   popupEvent.getCurrentSelectionInfo().getSelectedColumn())));
            }
            
            if (selectionType == SMTblSelectionInfo.CELL_SELECTION) {

                gridPanel.add(new JLabel("Selected Row"));
                gridPanel.add(new JLabel(String.valueOf(
                   popupEvent.getCurrentSelectionInfo().getSelectedRow())));
            }
            
            if (selectionType == SMTblSelectionInfo.ROW_SELECTION) {
           
                if (rows == null) {

                    gridPanel.add(new JLabel("Selected Row # "));
                    gridPanel.add(new JLabel("N/A"));
                }
                else {

                    for (int i=0; i < rows.length; i++) {

                        gridPanel.add(new JLabel("Selected Row # " +
                           String.valueOf(i + 1)));
                        gridPanel.add(new JLabel(String.valueOf(rows[i])));
                    }
                }
            }
        }

        // Display the name of the column the user brought up the menu over.
        //
        gridPanel.add(new JLabel("Column Name"));
        gridPanel.add(new JLabel(popupEvent.getColumnI18nName(column)));

        // Display the column number that the user brought up the menu over.
        //
        gridPanel.add(new JLabel("Column"));
        gridPanel.add(new JLabel(String.valueOf(column)));

        // Display the row number that the user brought up the menu over.
        //
        gridPanel.add(new JLabel("Row"));
        gridPanel.add(new JLabel(String.valueOf(row)));

 // Display the data value that the user brought up the menu over.
        //
        gridPanel.add(new JLabel("Cell Value"));
        gridPanel.add(new JLabel(popupEvent.getDataValue(row, column)));

        // Finish building the popup.
        //
        panel.add(gridPanel, BorderLayout.NORTH);

        // Define a close button so the popup can be closed.
        //
        JButton quitButton = new JButton("Close");
        panel.add(quitButton, BorderLayout.SOUTH);
        quitButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    frame.setVisible(false);
                    frame.dispose();
                }
        });
                    
        frame.getContentPane().add("Center", panel);
        frame.pack();
        frame.setVisible(true);
    }
}


Cell Editors

Sun Management Center console developer can specify a cell editor for any table cell that appears under the "Browser" tab of the Sun Management Center Details window.

This section contains information on:

This interface provides cell editors for any managed property.

You can extend the classes listed in the following table to define your own custom cell editor. When you click on an editable cell, the cell transforms into a widget allowing you to enter a value directly into the table:

TABLE  17-1   Classes Provided with the Core Application
SMTblCellEditor Base class for the other editors that does no special error checking.
SMTblStringEditor   A text editor that allows you to enter any valid text string.  
SMTblIntEditor   An integer editor that allows you to enter only valid integer values.  
SMTblFloatEditor   A floating-point editor that editor allows you to enter only valid floating point values.  
SMTblBooleanEditor   A boolean (checkbox) editor that cell editor allows you to set a boolean value to true or false with a standard Java checkbox widget.  
SMTblComboBoxEditor   A combo-box cell editor that allows you to select a choice from a standard Java pull down combo box widget.  

The application will beep and reject any invalid value.

All data types that can be defined in the module's module definition (-d.x) file automatically default to an editor that is appropriate for that data type. For example, a user can only enter integer values into a managed property defined to be of type INT in the module's Module Definition (-d.x) File.


Note - An agent object can augment the menu choices available in the table cell and table column header popup menus, but cannot alter or remove commands that have already been defined in the standard installation. Note also that integrated applications run in the same JVM as Sun Management Center.

 

To Specify that a Cell is Editable

The cell editor feature for a cell is automatically turned on for cells that are defined to be writable. Cells are defined to be writable with the access key being set to rw.

For more information on rw access, refer to "To Specify a Managed Property as Writable".

  1. If you want a cell to be writable, but do not want the custom cell editor feature be turned on so that the cell can be editable when you run the console, the following consoleHint must be set in the module-definition (-d.x) file.

consoleHint:editAccess = ro

  2. In addition to the consoleHint:editAccess, also specify the consoleHint:customCellEditor to make use of the Boolean (checkbox) and combo box cell editors.

 

To Use the Boolean Editor

   Specify the following in the module's module definition (-d.x) file:

consoleHint:customCellEditor = 
com.sun.symon.base.client.console.SMTblBooleanEditor

_
 

To Use the Combo Box Editor

   Specify the following in the module's module definition (-d.x) file:

consoleHint:customCellEditor = 
com.sun.symon.base.client.console.SMTblComboBoxEditor
consoleHint:optionList = "combo option 1" "combo option 2" ...

_

The consoleHint:optionList specifies what choices are available in the combo box.


 

To Implement a Customized Cell Editor

  1. Extending one of the provided classes.
  2. Define the consoleHint:customCellEditor appropriately as follows:

consoleHint:customCellEditor = MyCustomClass


 

To Specify a Custom Cell Editor

   Specify the following consoleHint inside the column definition for a table, or for any managed property:

consoleHint:customCellEditor = javaClass [ args ]

_

Rules for Java Implementation of the Cell Editor

The java class specified in the customCellEditor consoleHint must extend one of the following:

com.sun.symon.base.client.console.SMTblCellEditor
com.sun.symon.base.client.console.SMTblBooleanEditor
com.sun.symon.base.client.console.SMTblComboBoxEditor
com.sun.symon.base.client.console.SMTblFloatEditor
com.sun.symon.base.client.console.SMTblIntEditor
com.sun.symon.base.client.console.SMTblStringEditor

All class files and properties files associated with the user application to be integrated should be placed on the Sun Management Center server in the directory:

/opt/SUNWsymon/apps/classes

The classes may be packed together into a .jar file, or left as separate .class files.

Arguments to the java class must be separated by a space. Quotes may be used to specify an argument that includes a space.


Internationalization of the Cell Editor

When using a Combo Box Cell Editor, it is possible to internationalize the combo box choices. For more information, refer to the section "Conforming to Internationalization and GUI Guidelines" and "Internationalize a Module".


 

To Internationalize Cell Editors

  1. Define the following in MyModule-d.x file:

consoleHint:customCellEditor = 
com.sun.symon.base.client.console.SMTblComboBoxEditor
consoleHint:optionList = base.modules.MyModule:MyComboKey1 \
	base.modules.MyModule:MyComboKey2

  2. Define the following in MyModule.properties file:

MyComboKey1=Choice 1
MyComboKey2=Choice 2


 

To Test Custom Cell Editors

  1. Exit any Sun Management Center Host Detail screen.
  2. Restart the Sun Management Center agent.
  3. Bring back up the Sun Management Center Host Detail screen.
  4. Load the module that contains the cell editor, if necessary.
  5. Run your test.
  The Cell Editor is now available in the module.

Note - It is necessary to stop and restart the console after making any changes to the Java code that is placed in the /opt/SUNWsymon/apps/classes directory.

Example: Cell Editor

CODE  EXAMPLE  17-6 Cell Editor Example Code  
# EditCellManagedObject
#
# Displays examples of the various cell editors.
#
EditCellManagedObject = { [ use templates.dynamicmenu-version01\ 
-models-d.EditCellManagedObject ]

        # Text Editor
        #
        EditCellTblCellText = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Integer Editor
        #
        EditCellTblCellInt = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Floating Point Number Editor
        #
        EditCellTblCellFloat = {
                type   = passive
                access = rw
                consoleHint:editAccess = rw
        }

        # Checkbox (Boolean) Editor
        #
        EditCellTblCellBool = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor = 
com.sun.symon.base.client.console.SMTblBooleanEditor
        }



 # Combo Box Editor
 #
        EditCellTblCellCombo = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor = \ 
com.sun.symon.base.client.console.SMTblComboBoxEditor
                consoleHint:optionList       = entry1 entry2 entry3
        }

 # Custom Editor - uses SMCustomCellEdit class provided with this
 # example.  Input must start with the letter A.
 #
        EditCellTblCellCustom = {
                type   = passive
                access = rw
                consoleHint:editAccess       = rw
                consoleHint:customCellEditor = SMCustomCellEdit
        }
}


Cell Editor Java Code

CODE  EXAMPLE  17-7 SMCustomCellEdit.java  
/*
 * @(#)SMTblCellEditor.java   1.12 2000/01/31
 *
 * Copyright (c) 01/31/2000 Sun Inc. All Rights Reserved
 */
import java.awt.Toolkit;
import javax.swing.table.*;
import javax.swing.JTable;
import javax.swing.JTextField;
import java.awt.Component;
import com.sun.symon.base.client.console.SMTblCellEditor;

// SMCustomCellEdit
//
// Defines a custom cell editor that requires that the entry begin
// with the letter "A" (case-insensitive).
//
public class SMCustomCellEdit extends SMTblCellEditor {

    // Constructor
    //
    public SMCustomCellEdit() {
        super(new JTextField());
    }

    // getTableCellEditor
    //
    public Component getTableCellEditorComponent(JTable table,
        Object value, boolean isSelected, int row, int column) {

        ((JTextField)editorComponent).setText((String)value);
        return editorComponent;
    }

    // getCellEditorValue
    //
    public Object getCellEditorValue() {

        String returnValue = null;
        String data = ((JTextField)editorComponent).getText();

        if (data.toUpperCase().charAt(0) == `A') {
            returnValue = data;
        }
        else {
            Toolkit.getDefaultToolkit().beep();
        }

        return(returnValue);
    }
}


Configurable Details Window Interface

Users can only run es-details for objects modeled with es-device.
es-details is used to specify the tabs that will be made available for a given Node_Object_Type. The Node_Object_Type must match the value that was entered into the es-device script.


es-details

es-details is used to specify which tabs will be displayed on the Sun Management Center Details window. These tabs include both the tabs provided with the Sun Management Center product and user-defined tabs.


Syntax

The es-details script uses the following syntax:

% es-details [ -a ] [ -f inputfile ] -n Node_Object_Type [ -o ] [ -u ]

where:

-a   All: All tabs provided by Sun Management Center will be included.  
-f inputfile   File: The name of the es-details input file which contains a list of tabs to be used for this object type.  
-n Node_Object_Type   Node: Corresponds to the Node_Object_Type entered in the es-device script. The tabs will be modified for this object type.  
-o   Overwrite: Allows the es-details script to overwrite the output from a previous execution of the es-details script. Only meaningful when used with the -f option.  
-u   Undo: Restores the object type to its original state.  


Note - In the above example, the -f and -u options are mutually exclusive.

Since the es-details script is only to be executed for Node_Object_Type values that are associated with Sun Management Center agents, the script validates that the Node_Object_Type corresponds to a Sun Management Center agent and will generate an error otherwise.

The es-details script is only to be executed for Node_Object_Type values that were added with the es-device script. Please ses Chapter 17 for more information about the es-device script. The es-details script will generate an error if the specified Node_Object_Type was not modelled with
es-device.


Adding Tabs Provided by Sun Management Center

The following syntax is used in the inputfile to specify which tabs provided by Sun Management Center that will be available for objects of Node_Object_Type:

INCLUDE SMC_TABNAME SMC_TABNAME ...

Where SMC_TABNAME can be one of the following choices:

es-details generates an error message if you specify any other keyword for SMC_TABNAME.

The INFO tab must always be present on the Details screen and therefore is not a choice.

Even if you specify the tabs in any order in the inputfile, the tabs are always displayed in the same order in the Details Window. This order is, from left-to-right, INFO, BROWSER, ALARMS, VIEWLOG, APPLICATIONS, and HARDWARE.


Adding User-Defined Tabs

The following syntax is used in the inputfile to specify each user-defined tab that will be available for objects of Node_Object_Type:

APPEND TABNAME HELPKEY JAVACLASS

Where TABNAME is the name of the Tab to be added and JAVACLASS is the name of a user-provided Java class that meets the requirements in section 4.2: .

APPEND TABNAME HELPKEY JAVACLASS

The TABNAME must be entered in internationalized format and the associated property file must be properly installed. The format for the TABNAME value is as follows:

property_file:key

The format for the HELPKEY value is identical to the key:file or key:url format as specified for the "help" argument. For more information on the help key, refer to "Help Key Usage".

es-details generates an error message if the TABNAME, HELPKEY, or JAVACLASS arguments are not specified. The TABNAME and HELPKEY arguments must be in the correct format or an error message is generated.

Any user-defined tabs are placed to the right of the tabs that are provided by Sun Management Center. User-defined tabs will be ordered left-to-right in the order that they are defined in the inputfile.


Specifying an Open Default Tab when Launching Details Window

One tab can be specified as the tab that is open by default when the Details Window is launched. To specify this tab, specify the following line in the inputfile:

DEFAULT TABNAME

By default, the INFO tab is the default tab.

The specified default TABNAME must either be included in the inputfile or be included by using the es-details -a option, or an error message is generated. An error message will also be generated if you specify more than one default tab in the inputfile.


Example inputfile

The following is an example of an inputfile to the es-details program:

# es-details example input file.
# Include the following tabs provided by Sun Management Center
include browser alarms modules applications hardware
# Append a tab created by the user.
add SMTabHello:hellotab my-help:details.doc.html SMTabHello
# Specify the default tab to be the tab created by the user.
default SMTabHello:hellotab


Example: TabHello.java

CODE  EXAMPLE  17-8 SMTabHello.java  
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import com.sun.symon.base.client.SMRawDataRequest;
import com.sun.symon.base.client.console.SMAppBase;

public class SMTabHello extends SMAppBase implements 
ActionListener {

    private JLabel           helloText;     /* hello label             */
    private boolean          state;         /* hello state             */
    private int              num_clicks;    /* num of clicks           */
    private JLabel           statusMsg;     /* window status           */
    private int              agentPort;     /* agent port              */
    private String           agentHost;     /* agent host              */
    private SMRawDataRequest rawReq;        /* raw data request\ 
handle */

    // Constructor
    //
    public SMTabHello() {
        state      = false;
        num_clicks = 0;
    }

    // init - Build GUI
    //
    public void init() {
        setLayout(new BorderLayout());

        helloText = new JLabel("Hello World...");
        add(helloText, BorderLayout.NORTH);

        JButton button = new JButton("Change Text");
        add(button, BorderLayout.SOUTH);
        button.addActionListener(this);
    }

    // destructService
    //
    public void destructService() {
    }

    // startRequest
    //
    public void startRequest() {
    }

    // stopRequest
    //
    public void stopRequest() {
    }

    // actionPerformed - Change the text in the helloText label.
    //
    public void actionPerformed(ActionEvent e) {
        if (state == false) {
            helloText.setText("...from " + agentHost + " " + 
agentPort);
            state = true;
        } else {
            helloText.setText("Hello World...");
            state = false;
        }

        num_clicks++;

        statusMsg.setText("You have pressed the button " +\ 
num_clicks + " times.");
    }

    // setRawDataRequestHandle
    //
    public void setRawDataRequestHandle(SMRawDataRequest handle) {
        rawReq = handle;
    }

    // setAgentHost
    //
    public void setAgentHost(String host) {
        agentHost = new String(host);
    }

    // setAgentPort
    //
    public void setAgentPort(int port) {
        agentPort = port;
    }

    // setWindowStatusField
    //
    public void setWindowStatusField(Object statusField) {
        statusMsg = (JLabel)statusField;
    }
}


Removing Sun Management Center Default Tabs

To remove a tab normally included by Sun Management Center, do not specify it in the inputfile. If this is desired, then the es-details -a option must not be used.


Note - Removing the APPLICATIONS tab will cause any thrid-party applications that are integrated into this tab to be unavailable for machines of type, Node_Object_Type machines. It is not recommended that this tab be removed unless this behaviour is desired.

Re-Running es-details and Undo

   To re-run the es-details script as many times as desired for a given Node_Object_Type, you must use the -o option to overwrite the previous settings.
_

Note - It is not necessary to use the -o option the first time that the es-details script is run for a given Node_Object_Type.
   To return the Node_Object_Type to its state before the es-details script was executed the first time, use the -u option.
_

Note - The -u option stands for "undo".

Integration Guidelines and Notes

For more information, refer to "General Integration Guidelines".




Previous Next Contents Generated Index Home

Copyright © 2000 Sun Microsystems, Inc. All Rights Reserved.