JHotDraw Pattern Language

Creating Handles



A selected figure displaying resize handles

Direct manipulation of figures on a drawing is achieved through the use of Handles. The AbstractHandle class implements the Handle interface and provides default behaviour for all handles in the framework.

JHotDraw predefines several types of handle; they include ChangeConnectionHandle, ElbowHandle, LocatorHandle and PolygonHandle. It should be noted that because Handles tend to be specific to the figure they were created for, opportunities of reuse across different types of figure are rare. Therefore developers should expect to have to write their own handles either by sub-classing AbstractHandle or one of the above classes.

To add a handle to a figure the figures handles() Factory Method must be overridden. 

Resize handles are often required for figures in JHotDraw applications therefore the framework provides a utility class BoxHandleKit which simplifies adding resize handles to a figure

          public Vector<Handle> handles() {
        Vector<Handle> handles = new Vector<Handle>();
        handles.addElement(new GroupHandle(this, RelativeLocator.northWest()));
        handles.addElement(new GroupHandle(this, RelativeLocator.northEast()));
        handles.addElement(new GroupHandle(this, RelativeLocator.southWest()));
        handles.addElement(new GroupHandle(this, RelativeLocator.southEast()));
        return handles;
     }
          public Vector<Handle> handles() {
        Vector<Handle> handles = new Vector<Handle>();
        BoxHandleKit.addHandles(this, handles);
        return handles;
     }

When creating custom handles the dynamic behaviour of a handle has to be understood. Handles define three important methods: invokeStart(), invokeStep() and invokeEnd(). These methods are called when the mouse is respectively clicked, dragged and released on top of a handle. Every interaction with a handle will therefore follow a sequence where invokeStart will be called, invokeStep may be called (if the mouse is dragged) and invokeEnd will be called when the interaction ends. This granularity across the interaction allows the developer to control how the handle responds to the user input.

The appearance of a handle can also be altered. This might be appropriate to indicate the action the handle will perform or the current state the handle is in. To change a handle's appearance override its draw(Graphics) method.

To create handles at a position on a figure the locate() method should be redefined. This method returns a point around which the Handle will be centred.



Copyright Douglas Kirk