Using Groups and Shadows (Basics)

Visual Java introduces two new concepts: groups and shadows. Basic concepts about groups and shadows are discussed here, more advanced concepts are discussed in Using Groups and Shadows.

Groups

The primary purpose of Visual Java is to help you create groups. A group is a collection of shadows and other groups. To be considered a group, a class must be a subclass of the Group class.

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

Applications created using Visual Java are actually groups. A large application will typically consist of a base group that contains many other shadows and subgroups.

Shadows

A shadow is a wrapper class for an AWT component. To import a custom AWT component into Visual Java's palette, you must write a shadow class for it. Visual Java includes shadow classes for all the standard AWT components.

Both shadows and groups can be imported into the palette of Visual Java. For information on the getBody() method see Execute Code on the Operations page.

Attributes

Every shadow and group class has a set of attributes. When writing a group, much of what you do will 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:

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 sets 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.

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
Set to 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
set to true for AWT events

Message Handling (Callbacks)

Callbacks 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 "Group" implementation of "handleMessage" 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 will cause the mouseDown method to be invoked. By overridding the mouseDown method, all mouseDown 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;
    }
  }

Example:

This 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:

Using Groups and Shadows (Advanced)
Visual Java Overview
The Visual Menu
Visual Java Components
Laying Out GUI Interfaces
Generating Java Source Code
Adding Operations (Filters and Actions)
Visual Java Runtime Classes
Creating Menus
Adding Custom Components and Windows
Visual Java API Documentation
Visual Java Runtime Packages
Class Hierarchy
Index of all Fields and Methods