The controller

The controller manages the actions triggered by the end user, which have an immediate effect on the view, such as changing the zoom level. It is an instance of the class IlpEquipmentController.
The controller helps configure the view interactors and reacts to end-user interactions (such as requests to reshape or move objects) by forwarding actions to the handler, which updates the model directly or indirectly (through the data source).
The controller is used to support view parameters such as layers, zoom, and background. It also manages the toolbar and the interactors by defining which interactors are available in the toolbar.

Classes of the equipment controller

Each time an equipment component is created (instance of IlpEquipment), a default controller of class IlpEquipmentController is automatically created.
By default, a handler of class IlpEquipmentHandlerWithoutDataSource is instantiated. This handler is designed to forward end-user interactions directly to the equipment model. When a data source is attached to an equipment component, a different handler is instantiated, namely IlpEquipmentHandlerWithDataSource; this handler forwards end-user interactions to the data source instead of the model.

Using the equipment controller

Some of the most common methods of the class IlpEquipmentController can also be found in the class IlpEquipment.
Access to the controller API is through the method getController.
By default, no data source is associated with the equipment component, which means that the default handler is an instance of the class IlpEquipmentHandlerWithoutDataSource. When a mutable data source is associated with the equipment component through the method setDataSource, a new handler of class IlpEquipmentHandlerWithDataSource is instantiated, unless a custom handler has been set. The method setHandler allows you to set new handlers to the controller.
The controller manages the view and object interactors. By default, an instance of the class IlpEquipmentDefaultViewInteractor is set as the view interactor for the controller, but it is possible to define specific interactors for the view through the IlpEquipment API.

The handler

In the same way as the adapter passes information about the objects in the data source to the equipment component, the handler passes information in the opposite direction, that is, from the equipment component to the data source.
The information notified in this way includes:
  • Actions triggered by interactors for
    • Creating objects in the data source
    • Removing objects from the data source
    • Changing attributes of objects in the data source
    • Changing the parent object of an object in the data source
    • Expanding and collapsing container objects
  • Propagating position changes of objects
    The position changes are usually due to layout, zoom change, or interactors.
The handler has been designed to simplify the customization of user interactions without rewriting the controller.
Any user interaction with the equipment is processed by the equipment controller which delegates action to the equipment handler. The handler has two default implementations:
  • IlpEquipmentHandlerWithoutDataSource is attached by default to the controller and performs user interactions directly in the equipment model.
  • IlpEquipmentHandlerWithDataSource is automatically attached to the controller when a data source is connected with the equipment component. User interactions are executed inside the data source that will notify the adapter, and the adapter in turn will notify the equipment model. In this particular use case, changes will be reflected on all equipment components, if any, connected to the data source.
There are four types of handler:
The IlpEquipmentHandler interface indirectly extends all four types of handler.
Custom subclasses of IlpEquipmentHandler can be set using the controller.setHandler() method. It is possible to customize handlers separately by implementing the specific interface (for example, IlpNodeHandler) and setting it with the corresponding controller method (for example, controller.setNodeHandler()).
The handler has a reference to the data source in the form of an IlpMutableDataSource, and to the equipment adapter.
The JViews TGO default handler is only compatible with data sources that implement the IlpMutableDataSource interface.
You can customize the behavior of the handler by subclassing the class IlpEquipmentHandlerWithDataSource. A particular method can be overridden for each of the possible actions.
A custom handler that is a subclass of IlpEquipmentHandlerWithDataSource is automatically connected to a mutable data source.
It is the user's responsibility to manually connect a handler to a data source when one the following conditions applies:
  • The handler is not a subclass of IlpEquipmentHandlerWithDataSource.
  • The data source does not implement the interface IlpMutableDataSource.
    In this case, it is mandatory to create a custom handler and to design a way to connect the handler with the data source.
You can customize the way position changes are propagated by overriding the method propagatePositionToDataSource. In a typical situation where the client is active, position changes are propagated to the data source. Therefore, this method returns true by default. In a situation where the client has read-only access, you may want to allow only user-requested position changes or no position changes at all to be forwarded to the data source. You can achieve this result by allowing the method propagatePositionToDataSource to return false in the appropriate cases.
The handler is most often subclassed to allow you to customize the creation of new objects in the data source. The object interactors may need to be customized in the same way. A customized object creation interactor typically calls the controller method createObject with specific properties. The controller then forwards these properties to the handler. Finally, the method handleCreateObject of the handler parses the additional properties and creates the new objects.
By default, the handler creates new objects in two steps:
  1. The ID of the new object is created with the method createObjectId.
  2. The IlpObject corresponding to this ID is created with the method createObject.
You can customize each step separately by overriding these methods in a subclass.