# What Are Groups and Shadows?

GUI builder introduces two new concepts: groups and shadows. A shadow is a wrapper class for an AWT component. A group is a collection of shadows and other groups.

## Shadows

Shadows are wrapper classes for AWT components. Shadows do several things for you:

- Map component methods to attributes
- Delay the instantiation of AWT components
- Propagate AWT events to groups

Custom functionality may also be included in the shadow classes. For example, the window shadow resizes the window to its preferred size and maps the window when its `visible` attribute is set to true.

## Groups

A group encapsulates a set of shadows and subgroups. GUI builder is used to create new groups out of existing shadows and groups. When a new group is created, it can be imported into the GUI builder palette and can then be incorporated into other groups. New groups must be subclasses of the Group class.

Groups that are included inside other groups are called subgroups. The top-level group is called the base group. A tree of groups exists while the application is running. Messages sent by subgroups propagate up toward the top of the tree until they are handled or they reach the base group.

The interface to a group consists of a set of attributes and methods. The class Group defines a set of attributes and methods. Specific subclasses of the Group class add their own customized attributes and methods. The attributes and methods of the shadows and subgroups contained by a group are not automatically inherited.

Applications created using GUI builder are actually groups. A large application typically consists of a base group that contains many other shadows and subgroups.

## Attributes, Methods, and Messages

From an external viewpoint, a group is a single component that has a set of attributes, public methods, and messages.

### Attributes

Every shadow and group class has a set of attributes. Attributes for a group are defined in the constructor and are handled using the `getOnGroup` and `setOnGroup` methods. Support is provided for forwarding a set of attributes to one or more children of the group--a child being either a shadow or a subgroup.

When writing a group, many of your tasks involve setting and getting the attributes of the shadows contained by the group. Two methods are used to manipulate attributes:

    	public void set(String key, Object value);
    	public Object get(String key);

Example:

- To set the text of the button named "OK":

           gui.OK.set(, );

- To get the text of the button named "OK":

           String text = (String)gui.OK.get();

Every AWT component shadow inherits the following attributes:

       NAME		TYPE			DEFAULT VALUE
       ----		----			-------------
       name		java.lang.String	null
       visible	java.lang.Boolean	TRUE
       enabled	java.lang.Boolean	TRUE
       foreground	java.awt.Color		null
       background	java.awt.Color		null
       font		java.awt.Font		null

The button shadow defines an additional attribute:

       text		java.lang.String	button

In future releases the list of attributes will automatically be extracted from a shadow or group. This will make it possible to create a document listing all the attributes for each shadow class.

The `visible` attribute has a special behavior. When `visible` is set to true on a window for the first time, the window changes to its preferred size before display. Subsequent setting of the `visible` attribute to true or false will cause the window to be shown or hidden, but will cause no further resizing of the window.

### Methods

Most methods are custom methods written by the author of the group. There are some useful methods defined in the Group class itself, such as the `get`/`set` attribute methods.

### Message

A group will create messages and post them to their parent groups. A group does not need to have any knowledge of its parent. Instead, the parent can listen for a particular message from its subgroup and perform an action based on the message. A message can be sent by a subgroup, or it can be sent as a result of the delivery of an AWT event.

AWT stands for Abstract Windowing Toolkit. AWT is the GUI toolkit that is included with the JDK. This document assumes some familiarity with AWT, especially in the area of AWT events. For information on AWT, please refer to the JDK documentation.

A message has the following fields:

    String name

Name of the event; this is "AWT" for AWT events

    Object arg

Same as the `arg` field in the AWT event

    Object target

The shadow corresponding to the target field in the AWT event

    long when

Time of event creation.

    String type

Null for AWT events

    String targetName

Null for AWT events

    boolean isAWT

True for AWT events

## Message Handling (Operations)

Operations are defined in the group. When an AWT event is generated by an AWT component, it is translated into a message and then sent to the group that contains the component. (Actually, the group contains the shadow corresponding to the AWT component.) To intercept messages in the group, one or more of the following methods should be overridden (these are referred to as "message-handling methods"):

      public boolean handleMessage(Message msg);
      public boolean handleEvent(Message msg, Event evt);

      public boolean action(Message msg, Event evt, Object what);

      public boolean mouseDown(Message msg, Event evt, int x, int y);
      public boolean mouseDrag(Message msg, Event evt, int x, int y);
      public boolean mouseUp(Message msg, Event evt, int x, int y);
      public boolean mouseMove(Message msg, Event evt, int x, int y);
      public boolean mouseEnter(Message msg, Event evt, int x, int y);
      public boolean mouseExit(Message msg, Event evt, int x, int y);
      public boolean keyDown(Message msg, Event evt, int key);
      public boolean keyUp(Message msg, Event evt, int key);
      public boolean gotFocus(Message msg, Event evt, Object what);
      public boolean lostFocus(Message msg, Event evt, Object what);

`handleMessage` is invoked for all messages, whether the message is from a subgroup or is the result of an AWT event. The implementation of `handleMessage` in the Group class invokes `handleEvent` for all AWT events.

Code excerpt from "Group.java":

      public boolean handleMessage(Message msg) {
        if (msg.isAWT)
          return handleEvent(msg, (Event)msg.arg);
        else
          return true;
      }

`handleEvent` is only invoked for messages that come from AWT events. The implementation of handleEvent in the Group class invokes other methods depending on the type of the event. For example, `MOUSE_DOWN` events cause the `mouseDown` method to be invoked. By overridding the `mouseDown` method, all `MOUSE_DOWN` events originating inside the group will be caught.

Code excerpt from `Group.java`:

      public boolean handleEvent(Message msg, Event evt) {
        switch (evt.id) {
        case Event.MOUSE_ENTER:
          return mouseEnter(msg, evt, evt.x, evt.y);
        case Event.MOUSE_EXIT:
          return mouseExit(msg, evt, evt.x, evt.y);
        case Event.MOUSE_MOVE:
          return mouseMove(msg, evt, evt.x, evt.y);
        case Event.MOUSE_DOWN:
          return mouseDown(msg, evt, evt.x, evt.y);
        case Event.MOUSE_DRAG:
          return mouseDrag(msg, evt, evt.x, evt.y);
        case Event.MOUSE_UP:
          return mouseUp(msg, evt, evt.x, evt.y);

        case Event.KEY_PRESS:
        case Event.KEY_ACTION:
          return keyDown(msg, evt, evt.key);
        case Event.KEY_RELEASE:
        case Event.KEY_ACTION_RELEASE:
          return keyUp(msg, evt, evt.key);

        case Event.ACTION_EVENT:
          return action(msg, evt, evt.arg);
        case Event.GOT_FOCUS:
          return gotFocus(msg, evt, evt.arg);
        case Event.LOST_FOCUS:
          return lostFocus(msg, evt, evt.arg);

        default:
          return false;
        }
      }

The next example demonstrates action event handling. Action events are generated by AWT components and translated by `handleEvent()` into calls on the action method. The example assumes the creation of a GUI description containing a button named "OK" and a button named "Cancel." If an action event originates from the "OK" button or the "Cancel" button, a message is printed.

The AWT button component generates an action event when it is clicked.

    public boolean action(Message msg, Event evt, Object what) {
      boolean handled = false;

      if (msg.target == gui.ok) {
        System.out.println("OK");
        handled = true;
      }
      else if (msg.target == gui.cancel) {
        System.out.println("Cancel");
        handled = true;
      }

      // All message handling methods should be true if the message
      // was handled, and false otherwise.
      //
      // The return value determines if the message should be passed
      // on to the operation classes, and subsequently on up the
      // group tree. AWT messages are never propagated up the group
      // tree regardless of the return value, but they are forwarded
      // to the operations classes depending on the return value.
      // [ operation classes are currently not implemented ]

      return handled;
    }

See also:

  More On Groups and Shadows
  Generating Java Source Code
  What Is a Component Operation?
  Adding Operations to Components
  GUI Builder Runtime Classes
  Adding Operations to Menus
  Importing Components

  Visual Java GUI Builder API Documentation
    Visual Java GUI Builder Runtime Packages
    Class Hierarchy
    Index of All Fields and Methods