Customizing the interactor of selected graphic objects

The selection interactor (IlvSelectInteractor) is also a view interactor. It allows you to select, move and reshape objects. The way an object is reshaped depends on the type of the object. For example, you can only change the size of an IlvRectangle while you can add points to an IlvPolygon. The dependency of possible interaction on the type of the object comes through the object interactor associated with the selection of the object.
If an object is selected, the method makeSelection is called to create a suitable selection object (subclass of IlvSelection. This selection object is drawn on top of the selected object.
Since IlvSelection is a subclass of IlvGraphic, it can have object interactors. When the select interactor moves the mouse over a selection object, it queries for the object interactor of the selection object.
If no object interactor is explicitly set on the selection object, it calls getDefaultInteractor to retrieve the class name of the default interactor and then sets the object interactor of the selection object to an instance of the default interactor.
Then, the select interactor forwards all events to the object interactor of the selection. This object interactor receives the mouse events as long as the mouse is over the selection object.
The object interactor of the selection object can react on the received events by reshaping the original selected object. In most cases, the object interactor of the selection object does not modify the selection object itself but rather the original selected object.
To create a new graphic object class with a customized selection and customized reshape interaction on the selected object:
  1. Create your new derived class of IlvGraphic as described in Creating a new graphic object class.
  2. Create a new derived class of IlvSelection as described in Creating your own selection object.
  3. Create a new object interactor that works on the selected object instead of the selection.
  4. In the derived graphic class, override makeSelection to return an instance of the new selection class.
  5. In the new selection class, override getDefaultInteractor to return the class name of the new object interactor. Alternatively, you could call setObjectInteractor on the selection object when it is allocated. The former is more convenient if you want to have the same interactor for all instances of the new subclass of IlvSelection, while the latter can be used if you want to assign specific object interactors to specific instances of the selection.
The following code example creates a new graphic subclass MyMarker that has a special selection object MyMarkerSelection. If the marker is selected, the object interactor MyMarkerEdition becomes active. Each click in the marker selection changes the type (and therefore also the shape) of the marker.
public class MyMarker extends IlvMarker
{
   ...
 
  public IlvSelection makeSelection()
  {
    return new MyMarkerSelection(this);
  }
}

public class MyMarkerSelection extends IlvUnresizeableDrawSelection
{
  ...

  public String getDefaultInteractor()
  {
    return MyMarkerEdition.class.getName();
  }
}

public class MyMarkerEdition extends IlvReshapeSelection
{
  public MyMarkerEdition()
  {
    super();
  }

  protected boolean handleButtonDown(IlvDrawSelection sel, MouseEvent event,
                                     IlvObjectInteractorContext context)
  {
    // each click with the left mouse button into the selection object
    // changes the type of the selected object

    if ((event.getModifiers() & InputEvent.BUTTON2_MASK) != 0 ||
        (event.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
      return true;

    MyMarkerSelection msel = (MyMarkerSelection)sel;
    MyMarker marker = (MyMarker)msel.getObject();

    // even though the object interactor is on the selection, it
    // modifies the selected object, not the selection
    final int tp = (marker.getType() >= 512 ? 1 : marker.getType() * 2);
    IlvGraphicBag bag = marker.getGraphicBag();
    if (bag == null)
      marker.setType(tp);
    else
      bag.applyToObject(marker, new IlvApplyObject() {
          public void apply(IlvGraphic g, Object arg) {
            ((MyMarker)g).setType(tp);
          }
        }, null, true);
    return true;
  }
}