Creating Your Own Components

Introduction

When an existing SAS/AF software class does not provide the behavior you desire, you can extend the functionality of an existing class by creating a subclass. Extending a class be as simple as creating a new frame class with a blue background or as complex as writing your own model and view classes. By virtue of the SCOM framework, you can take advantage of object-oriented functionality and add to or modify any of the existing properties of a class. Subclassing and class-wide modifications are performed in the Class Editor or with SCL class syntax.

Subclassing Methodology

When creating a subclass, you should follow these general steps:
  1. Decide which class to subclass. Normally this is the class that contains the behavior closest to the functionality you want to implement.
  2. Extend the existing properties by modifying or adding attributes, methods, events, or event handlers.
  3. Test the subclass with either of these methods:
    • Add the new class to the Components window so that it appears in the list of available classes and can be tested on a frame.
    • Instantiate the subclass using the SCL _NEW_ or _NEO_ operators and test it programmatically.

Creating a Simple Subclass by Overriding an Attribute

Introduction

As an example of both the methodology and the techniques that are used to create a simple subclass, the following example demonstrates how to build a simple button class that closes a frame. Because you include a “Close” button of some sort on nearly every frame you build, modifying a subclass of the existing pushbutton_c class will save you from setting the same attributes each time you want such a button. After creating the class and adding it to the Components window, you simply drag your Close Button class onto the frame; no coding is required, and you do not have to set its properties.
You can add or override properties using either the Class Editor or the Properties window. Although they look alike and contain what appears to be the same information, it is important to understand the differences between these two tools:
  • Changes that you make in the Class Editor affect all instances that are based on the class, whether they appear on different frames or not.
  • Changes that you make in the Properties window affect only the specific instance of the class. The Properties window displays public properties for each instance on a frame.

Creating the Close Button Subclass

This example creates a subclass of the push button control, using the Class Editor to override the values of the label and commandOnClick attributes. For more information on specific tasks in this example, see the SAS/AF online Help.
To create a button that closes a frame:
  1. Create a new catalog named sasuser.buttons to hold the new class.
  2. Create a new class with a description of Close Button. The description is used to identify the class in the Components window. Unique descriptions are required (if you want to determine the difference between components with accuracy), but are not programmatically verified.
  3. Select sashelp.classes.pushbutton_c.class as the parent class. Obviously, to know which class to subclass you must be familiar with the class hierarchy.
  4. Override the label attribute. Specify Close as the initial value of the label attribute. The label attribute represents the text that appears on the button.
  5. Override the commandOnClick attribute. Specify End as the initial value of the commandOnClick attribute. The commandOnClick attribute represents the command that is executed when the button is clicked.
  6. Save the class. For the entry name, specify CloseButton (with no spaces).
    You may also include a short description of what the class does, such as Close frame button. This description, if provided, overwrites the description provided in step 2 above.

Testing the Close Button Subclass

The Close Button class is now ready for use. Follow these steps to make the class available for use and testing:
  1. Create a new frame.
  2. Make the Close Button available for use in the Components window by right-clicking in the Components window and selecting Add Classes. Select or enter the sasuser.buttons.closebutton.class. The Close Button class appears in the Components window.
  3. Drag a Close Button to the frame. The button label is Close.
  4. Test the functionality of the button by selecting Buildthen selectTest. When the frame appears, click Close to close the frame.
The example demonstrates how you can create a very useful class without any programming.

Creating a Subclass by Overriding a Method

Introduction

When you create a new class, you must decide what unique actions you want to include in its definition. The actions are defined by their methods. Methods from the parent class are inherited by the subclass that you create. Although method inheritance is one of the primary benefits of object-oriented programming techniques, there are times when you will want to augment a class's functionality by adding new methods or overriding inherited methods:
  • Create a new method for your subclass if you want to add behavior that is not currently available in the parent class.
  • Override an existing method to modify the behavior of the parent class in your subclass. An overridden method is one that extends a method that has the same name and signature on a parent class. In effect, overridden methods add some kind of functionality to a class, but they also call the same method on the class's parent to ensure that the method's core functionality is preserved. When overriding a method, you provide a new method definition, but you cannot change the method's name, signature, or scope. You can also overload methods to complement existing behavior. For more information on overloading, see Overloading Methods.
To demonstrate how you can add new behavior to a class, consider the Close Button class that was presented above. Although the Close Button class is useful, a user of your application might accidentally click a “Close” button. To help prevent such mistakes, you could add a confirmation dialog box to the Close Button class. The class could have the following behavior:
  • When the Close button is clicked, a dialog box is displayed to confirm the action.
  • If the user selects Yes, the frame closes. Otherwise, the frame remains open.
To implement this behavior in a new class, review the existing class:
  • Does the parent class provide a behavior when the button is clicked on the frame?
    After deciding to augment the behavior of a class, you must decide whether to override an existing method or add a new one. In the Close Button class, the _onClick method that serves as the event handler is called whenever the button is clicked. You can override this method and have the new implementation display the dialog box. If you override a method, you should execute the same method on the parent by calling _super() in your code.
See the SAS/AF online Help for assistance with specific tasks.

Overriding an Existing Method

To add new behavior to the Close Button class, override the _onClick method:
  1. If you created the Close Button class that was presented earlier, you must re-inherit the commandOnClick attribute that was overridden so that the END command will not be executed when you click the button.
  2. In the Class Editor, override the inherited _onClick method. The State metadata item changes to 'O'.
  3. The _onClick Source Entry metadata item now contains the four-level name of the SCL entry that will contain the new code: sasuser.buttons.closebutton.scl.
  4. Display the Source for the method via the pop-up menu and enter the following code in the SCL entry:
    useclass sasuser.buttons.closebutton.class;
    
    onclick: method;
       _super();   /* call onClick method on parent */
       dcl num rc;
       dcl list messageList = {'Close this frame?'},
           char(1) sel;
       sel = messageBox(messageList, '?', 'YN');
       if sel = 'Y' then call execcmd('end;');
       rc=dellist(messageList);
    endmethod;
    enduseclass;
  5. Compile and close the SCL entry.
Note: For more information on methods and SCL, see Implementing Methods with SCL, and Adding SAS Component Language Programs to Frames.

Testing the Overridden Method

After you have created and saved the class, you can test the new behavior. If you created the frame with the “Close” button from the last example, open that frame and test it to see the new behavior. The changes to the Close Button class are picked up automatically when the frame is opened and the Close Button object is instantiated.
If you do not have a frame with the Close Button object already on it, follow these steps to test the new behavior of the Close Button:
  1. Create a new frame.
  2. Right-click inside the Components window and select Add Classes from the pop-up menu to add the new class.
  3. Drag a Close Button object from the Components window onto the frame.
  4. Test the frame.

Extending a Class with New Attributes and Methods

Introduction

Although the Close Button class presented in the previous example is useful, you might not always want a confirmation dialog box to be displayed when a frame is closed. To implement this behavior, review the following question:
  • Does the parent class provide data that could be used to specify whether to display a confirmation dialog box?
    You can check attributes on the class to see whether you need to override an existing attribute or add a new attribute to maintain this information. Since the Close Button class does not have such an attribute, you have to add a new one to the class.
To add flexibility to the Close Button class, add an attribute to the class that enables developers who use the object in their frames to specify whether to display the confirmation dialog box.
To add an attribute to the Close Button class:
  1. Close all frames that contain a version of the Close Button class.
  2. Open the sasuser.buttons.closebutton.class class if it is not already open.
  3. Create a new attribute called displayExitDialog. This will be the attribute that determines whether the confirmation dialog box should be displayed. Attributes keep data on a component where it can be easily accessed by other components via SCL or attribute linking.
  4. Set the following metadata items for the new displayExitDialog attribute:
    • Type = Character
    • Initial Value = Yes
    • Valid Values = Yes,No
    • Category = Behavior

Editing the Existing Method to Query the New Attribute

Edit the existing overridden _onClick method on the Close Button class by adding four lines of code:
useclass
sasuser.buttons.closebutton.class;

onclick: method;
   _super();     /* calls the parent's _onClick method */

   if upcase(displayExitDialog) = 'NO' then
      call execcmd('end;');
    else do;
       dcl num rc;
       dcl list messageList = {'Close this frame?'},
           char(1) sel;
       sel = messageBox(messageList, '?', 'YN');
       if sel = 'Y' then call execcmd('end;');
       rc=dellist(messageList);
    end;
endmethod;
enduseclass;

Testing the New Attribute and Method

After saving the class, test the new attribute:
  1. Test the frame and the Close Button class as they are when the frame opens to see the default Close Button behavior. The confirmation dialog box is displayed.
  2. To see the alternate behavior of the Close Button, use the Properties window to set the Close Button object's displayExitDialog attribute to No.
  3. Re-test the frame. No confirmation dialog box is displayed.