Copyright (c) 1999, 2000 Silicon Graphics, Inc. All Rights Reserved.

Overview | Basic Concepts | GUI Components | Architecture | How To Write An App

How to Customize the Task Manager

The Task Manager is a front end to all of the Tasks in a Rhino-based product. The Task Manager is customized for each Rhino product, but the basic interface appears the same for each product so that Users are presented with a common look and feel. Basic customization is accomplished through the creation of a product-specific properties file. It is also possible to plugin Java classes to handle more complex situations.

The Task Manager window has four parts, each of which can be customized to some degree.

For the duration of this document, let us assume that you are customizing the Task Manager for the product: Rhino Example.

The Task Manager Properties File

Basic customization of Task Manager is accomplished through the product-specific properties file called TaskManagerP.properties. This file typically resides in the top of your package hierarchy. For example,
    myWorkArea/package/com/sgi/rhexamp/TaskManagerP.properties 
The property names are documented in the Rhino class TaskManagerProperties and default values, when provided, exist in com.sgi.sysadm.manager.TaskManagerP.properties.

Customizing the Table of Contents

First you will want to customize the header, or title shown in the Table of Contents panel. This is accomplished by defining a property in TaskManagerP.properties as follows:
    TaskManager.TOC.title = <B>Rhino Example Manager</B>
Next, you will want to create the product-specific list of page links. This is accomplished via an ordered property set called TaskManager.TOC.item<n>, where each item represents one page link or a separator. For each page, you specify a page type, a page title, and a page target.

For example, to specify a text overview page as the first page, you would add the following properties to the TaskManagerP.properties file:

    TaskManager.TOC.item0 = text
    TaskManager.TOC.item0.title = Overview
    TaskManager.TOC.item0.target = \
        <P> Rhino Example Manager Graphical User Interface \
        provides access to the tasks that help you set up and \
        administer your Rhino Example objects. \
        <P>The tasks are organized into the categories \
        described below.  To view a category, click on it in the \
        <P> RhinoExample Task Manager Graphical User Interface (GUI) \
        provides access to the tasks that demonstrate use of \
        the Rhino infrastructure. \
        <P> \
        The tasks are organized into the categories described below. \
        To view a category, click on it in the column at left.<P>\
        <B>Overview</B> -- \
        Display this overview document. <P> \
        <B>Search</B> -- \
        Use keywords to search for a specific task. <P>\
        <B<RhinoExample Tasks</B> -- \
        Example tasks that demonstrate the use of the Rhino infrastructure.
Note that for text pages, the 'target' contains the actual text to be displayed on the page.

Now let's imagine that you want the next page to be a search page that allows Users to find the Task they are interested in via keyword. Rhino provides a Class Page plugin SearchPanel that indexes all of the Tasks and Tasksets by keyword. Here's how the page would be specified in TaskManagerP.properties:

    TaskManager.TOC.item1 = class
    TaskManager.TOC.item1.title = Search
    TaskManager.TOC.item1.target = \
        com.sgi.sysadm.manager.taskManager.SearchPanel
The target for a page of type class is the CLASSPATH relative name of the page plugin, which must implement the TaskManagerPanel interface.

Next we'll add a separator in the Table of Contents, which does not require the title or target specifiers:

    TaskManager.TOC.item2 = separator

Finally, we'll add a Task List page. Task List pages display an optional list of Tasksets (also known as Metatasks), a separator, and then an optional list of Task Groups. Tasksets provide guidance in accomplishing a high level goal that may involve multiple tasks. Task Groups are (possibly ordered) lists of Tasks that are closely related, usually by the type of object they operate on. For example, Tasks that all operate on User accounts are likely to be in the same Task Group.

    TaskManager.TOC.item3 = tasklist
    TaskManager.TOC.item3.title = RhinoExample Tasks
    TaskManager.TOC.item3.target = RhinoExampleTasks
The target for a Task List page will be used as a key to optional property sets that describe the list of Tasksets (also known as Metatasks) and Task groups to display on the page. For example, the RhinoExample Tasklist page will have a single Task group:
    TaskManager.RhinoExampleTasks.taskGroup0 = MyTaskGroup
    TaskManager.RhinoExampleTaskGroup.introText = \
        <B>Rhino Example Tasks</B>
The introText property is the text to display at the top of the Task Group. The Task Group itself is installed in the TaskRegistry on the server, in a directory named "MyTaskGroup". See Plugging in a Task Group later in this document for details.

If we also wanted to display a list of Tasksets on the RhinoExample Tasks page, the properties might look like this:

    TaskManager.RhinoExampleTasks.metatasksText = The following tasksets can \
        help you keep your system  up and running in production \
        mode.  Find the taskset that suits \
        your needs, then click to launch it.

    TaskManager.RhinoExampleTasks.metataskItem0 = \
        com.sgi.rhexamp.metatask.FirstExampleTaskset
    TaskManager.RhinoExampleTasks.metataskItem1 = \
        com.sgi.rhexamp.metatask.SecondExampleTaskset
The metatasksText is displayed above the entire list of Taskset links (and is optional).

Each metataskItem refers to another Properties file that describes the contents of the Taskset, which will launch in a separate window when activated. Here is an example of the contents of a Taskset properties file:

    #
    # Properties for First Example Taskset
    #
    Metatask.name = First Example Taskset
    Metatask.keywords = keywords to help users find this Taskset

    Metatask.text = \
        <B>Achieve a High Level Goal</B><P> \
        This taskset lists different ways to achieve a goal. \
	Here are some of the options: \
        <UL>\
        <LI><A href=task.com.sgi.fsmgr.task.ModifyClusterTask>
        <B>Modify an Example</B></A> -- \
        Set Example attributes \
        <LI><A href=task.com.sgi.fsmgr.task.DefineMachineTask>
        <B>Define an Example</B></A> \
        -- Create an Example. \
        </UL>
A Taskset (or Metatask) has three attributes set in its properties file: the name, keywords, and text. The text specified will be used to create a RichTextComponent that can contain links that launch Tasks, other Tasksets, or glossary entries when activated.

The font and color of the Table of Contents panel, title label, and page links can all be customized as well. See TaskManagerProperties for details.

Plugging in a Task Group

A Task List page can contain one or more Task Groups. Each Task Group is a (possibly ordered) list of Tasks that are closely related, usually by the type of object they operate on. For example, Tasks that all operate on User accounts are likely to be in the same Task Group.

Task Groups are specified in the properties for a Task List page rather than the Tasks themselves to allow new Tasks to be plugged in to the Task Manager without requiring the images to be re-shipped. For example, a new product could be created that adds Tasks to existing Task Groups, and they will automatically appear in the Task Manager the next time it is launched.

Tasks are plugged into Task Groups via the Task Registry on the server. Here are the steps needed to create a new Task Group named myTaskGroup in the Task Registry and add an ordered set of Tasks to that group:

  1. cd myWorkarea/taskRegistry
  2. mkdir MyTaskGroup
  3. copy the Makefile from any existing Task Group or Task Category into MyTaskGroup (you should have an existing Task Group and Task Category if you created your Rhino ism using the Make Rhino Ism Task).
  4. cd MyTaskGroup
  5. For each Task you want to add:
    1. touch {4-digit order key}.com.sgi.{myProduct}.task.{taskName}
    2. p_modify -f {new file name from previous step}
  6. p_modify Makefile
  7. Edit the Makefile, replacing the existing file names with the new files added in the previous steps.
  8. cd ..
  9. p_modify Makefile
  10. add MyTaskGroup to the list of directories to build
  11. cd myWorkarea/build
  12. update the idb with the new Tasks
  13. p_integrate
  14. p_finalize
For example, if you wanted to add three Tasks to the MyTaskGroup named "AddRhinoExampleTask", "ModifyRhinoExampleTask" and "DeleteRhinoExampleTask", in that order, you would do the following: You will need to build and install the taskRegistry onto your server.

Adding Buttons to the Button Bar

By default the Button Bar at the bottom of the TaskManager window has a Close button. When pressed, the Close button will terminate the Task Manager application but any other windows launched from Task Manager will stay open. The Close button will always appear as the rightmost button.

Buttons are added by creating an ordered property set in the Task Manager properties file. For example:

    TaskManager.buttonItem0 = First Button
    TaskManager.buttonItem0.target = com.sgi.myProduct.myFirstPlugin
    TaskManager.buttonItem1 = Second Button
    TaskManager.buttonItem1.target = com.sgi.myProduct.mySecondPlugin
Each button is given a name that will be displayed on that button as well as a target class that should be launched when the button is activated. The target class must implement one of TaskManagerFrame or TaskManagerAction. The first button added will be the leftmost button on the button bar. Subsequent buttons will be added to the right of the previous button but always to the left of the Close button.

Customizing the Task Manager Frame Title

By default, the Task Manager Frame Title will display a static string that includes the server name. This static string may be customized via a property. For example:
    TaskManager.frameTitle = RhinoExample Manager (on {0}) 
Where the argument {0} is replaced with the server name.

If you wish to have a dynamic title that, for example, changes when the state of an object on the server changes, then you will want to use a TaskManagerTitleRenderer. A title renderer is a class that is responsible for keeping the title string up to date. It can monitor the server and make updates as desired. To plugin a title renderer, you use a property in the Task Manager properties file. For example:

    TaskManager.titleRenderer = com.sgi.myProduct.plugin.MyTitleRenderer

Adding Code that Runs at Startup

Some products need to run initialization code when their Task Manager starts up. For example, a product might want to set up default values for TaskData that will be used by product-specific tasks. A TaskManagerInitPlugin is where that default-setting code should reside. Multiple TaskManagerInitPlugins can be plugged in via the Task Manager properties file. For example:
    TaskManager.initPlugins0 = com.sgi.myProduct.plugin.MyFirstInitPlugin
    TaskManager.initPlugins1 = com.sgi.myProduct.plugin.MySecondInitPlugin
The initialization plugins will be run, in order, as the first operation when the Task Manager is launched.

Running Task Manager

Let's suppose you have created your TaskManagerP.properties file in myWorkArea/package/com/sgi/myProduct and CLASSPATH includes "myWorkArea/package". To launch your customized Task Manager, you would enter the following command:
    java com.sgi.sysadm.manager.TaskManager -p com.sgi.myProduct
To launch the Task Manager programmatically, you need to know the CLASSPATH relative name of the product (so that Task Manager can find the product-specific properties file. For example:
    void launchTaskManager() {
        // Go busy while launching
	_uic.busy(new ResultListener() {
	    public void succeeded(ResultEvent event) {
		TaskManager tMgr = new TaskManager("com.sgi.myProduct");
		tMgr.initApp();
		tMgr.run(_hc, new RApp.RAppLaunchListener() {
		    public void launchSucceeded(RApp.RAppLaunchEvent event) {
			_uic.notBusy();
		    }
		    public void launchFailed(RApp.RAppLaunchEvent event) {
			_uic.notBusy();
		    }
		    public void launchAlreadyRunning(
			RApp.RAppLaunchEvent event) {
			_uic.notBusy();
		    }
		});
	    }
	    public void failed(ResultEvent event) {
	    }
	});
    }
See RApp for more information on launching a Rhino application.