Writing Non-Component Locators: Anatomy of a JSNonComponentLocator


You can find the API for this class in the JavaStar API Reference.

There are two methods that must be provided:

  1. JSNCLData findObject(Component c, AWTEvent e)

  2. JSNCLData getNamedObjectData(Component c, String name)

Finding the JSNCLData while Recording

The findObject() method must determine what object is at a given mouse position. To do this it must:

  1. Ensure that the component and event are appropriate for this NCL.
    JavaStar will pass the pair to each NCL on the list of locators until a value is returned or it has iterated the entire list. So the NCL for a JTree, for example, must be sure that the component passed is an instance of a JTree, and the event is a mouse event. Otherwise, it should return null. Here is the code in Tree.java that ensures this is a JTree and a mouse event:

Note the cast of the component to the JTree when it is certain that the component is a JTree.

  1. Locate the nearest component at this position.
    The NCL must determine the component that is appropriate for that event, and at the position within the containing component. How it does that depends on the methods available in the component. For a JTree, the NCL uses the getClosestPath() method to locate the full path, then gets the row index for that path. Here is the code:

  2. Create a unique name for the contained component.
    There are two parts to the name: its location within the containing component, and a confirming string that can be used to ensure the same component is at that location. Think of the location as a street address of a home. Think of the confirming string as the names of the people in the home. To find people, you need to both locate their address and ensure they still live there. When a script is played back, that location must exist and that same component must be in that location.
    For the JTree, finding the location is easy. Mozart is the fourth row, and the NCL uses the integer 4 as the index. The confirmation is not quite as easy. Simply using the string "Mozart" may not ensure it is the correct component, as there may be many "Mozart" entries in the tree. To be unique, the string must contain the path to Mozart. The Tree.java uses the various methods available to get the row path, parse it to individual objects, and concatenate a path, separated by the ## delimiter, of the "toString()" titles of each object. The resulting name, then, is 4:"Music##Classical##Mozart".

  3. Locate the position of the contained component within the container.
    There needs to be a consistent way to state the boundaries of that component relative to its container. Figure 11-2 shows a logical rectangle around the row. The upper boundary of that rectangle is at point (40,72) within the JTree. A click at (44,84) lies within that row.

    A Row contained within a Tree
    The Point of the Non-Component is a fixed position from which JavaStar can consistently calculate the relative position of the multi-click. In the case of the Mozart example, the point is at the x, y coordinates of 40,72.
    If JavaStar calls findObject() with a mouse click at 44,84, the NCL finds the row at 40,72. JavaStar sees that point in the returned JSNCLData, and translates the mouse click to be relative to that row. The mouse click coordinates viewed in the script, then, are 4 (44 minus 40), 12 (84 minus 72).
    The row bounds of 40,72 were obtained by using the getRowBounds() method of JTree.

  4. Get the actual component.
    The last part of the JSNCLData is the component itself. The NCL provides the component at the appropriate level. For a JTree, that was determined to be the TreeNode at that level. If this click was not on a tree node, no object, and no JSNCLData, would be returned.

The other "half" of the NCL is to be able to generate the JSNCLData based on the unique name, rather than a coordinate.

Retrieving a Named Non-Component

When a script is played back, JavaStar needs to find the actual component clicked upon to evaluate whether a verification continues to pass against that component. JavaStar has the unique name found at the time of recording, and the event logged against the component. It needs to verify that the appropriate non-component exists, and invoke the necessary methods against that component to evaluate a verification.

The NCL must provide a method, getNamedObject(), to get the JSNCLData for a component based on its name. The NCL is provided the containing component, and the unique name created at the time of recording the script.

In our example, getNamedObject() is passed the JTree, and the string "4:Music##Classical##Mozart".

These are the things that must occur:

  1. Ensure that the component is appropriate for this NCL.
    In this case, the component must be a JTree.

  2. Parse the string to the location, and the confirmation.
    The location is 4, in our example, and the confirmation is the string version of the row path.

  3. Confirm the location exists.
    In this case there must be a fourth row in the JTree. If there isn't, the method returns null.

  4. Confirm the proper component is at that location.
    The NCL regenerates the path string in the exact same manner as it did when recording, and ensures it is the same as the one given to the method. If it is, we have the component. If not, null is returned.

  5. Create the NCL Data for that component.
    This is done exactly as it was for findObject(). See steps 3-5 of "Finding the JSNCLData while Recording", above.

Once JavaStar has the component, it can run required methods on it to verify that the tests pass.




Send feedback to JavaStar-feedback@suntest.com
Copyright © 1998 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, CA 94303. All rights reserved.