The IlvLabelingModel Class

The methods defined in the IlvLabelingModel class can be divided into several categories: those that provide information on the structure of the labels and obstacles, on their geometry, on their overlap penalty, and notification of changes in the manager.
They are described in the following sections:
UML diagram
showing IlvLabelLayout, IlvLabelingModel, IlvDefaultLabelingModel,
IlvManager, and Custom Labeling Model
Class diagram for IlvLabelingModel

Information on the structure of labels and obstacles

The following methods of the IlvLabelingModel class allow the layout algorithms to retrieve information on the labels:
Decides whether an object is a label.
Enumerates all existing labels.
Returns the number of labels that exist.
The following methods allow the layout algorithms to retrieve information on the obstacles in a similar way:
boolean isObstacle(Object obj)  
boolean isPolylineObstacle(Object obj)  
Enumeration getObstacles()  
int getObstaclesCount()  
For optimization purposes, the labeling model distinguishes between normal obstacles and polyline obstacles. While normal obstacles cover the major part of their bounding box, polyline obstacles have a line width and range over intermediate points; thus they cover only a small part of their bounding box.
Since a polyline obstacle is an obstacle, both isObstacle and isPolylineObstacle return true for a polyline obstacle.

Information on the geometry of labels and obstacles

For labels and obstacles, the label layout can retrieve the bounding box with the method:
IlvRect boundingBox(Object labelOrObstacle)  
For the special polyline obstacles, the label layout can retrieve the precise shape of the polyline with the methods:
float getPolylineWidth(Object polylineObstacle)  
IlvPoint[] getPolylinePoints(Object polylineObstacle)  
The following method moves a label to the new position.
void moveLabel(Object label, float x, float y, boolean redraw)  

Overlap calculation

A good label layout avoids overlaps. Thus, the calculation of overlap values is an important step of the algorithm. The speed of the layout algorithm depends crucially on the speed of the overlap calculation. The labeling model provides the following methods for overlap calculations:
Calculates the overlap between two labels.
Calculates the overlap between a label and a normal obstacle.
Calculates the overlap between a label and a polyline obstacle.
These methods return a positive penalty value that indicates how much the objects overlap.
  • The returned value is 0 if the objects do not overlap.
  • A smaller overlap value designates less overlap than a larger overlap value. The actual number is arbitrary and depends on the implementer of the labeling model. For example, if all objects are rectangles, then it could be the size of the overlapping area of the rectangles.
Typically the overlap value is calculated before the label is moved. It is calculated for a speculative label position, not for the real label position. Hence, the speculative bounding box of the label is passed as an argument. Similarly, the bounding box (or polyline shape) of the obstacle is passed as an argument as well. The meaning of the returned value is the overlap penalty if the label were placed at its passed bounding box, and the obstacle were placed at its passed bounding box.
If the overlap methods return a positive nonzero penalty only when the speculative bounding boxes overlap, then the following method can return true :
boolean isBoundingBoxDependent() 
This method exists mainly for quadtree optimization purposes.

Notification of changes

The following methods of the IlvLabelingModel class allow a layout algorithm to be notified of changes in the data structures:
void addLabelingModelListener(LabelingModelListener listener)  
void removeLabelingModelListener(LabelingModelListener listener)  
void fireLabelingModelEvent(Object obstacleOrLabel, int eventType, boolean 
adjusting) 
void fireLabelingModelEvent(LabelingModelEvent event)  
A “change” can be a structural change (that is, a label or obstacle was added or removed) or a geometrical change (that is, a label or obstacle was moved or reshaped). The event type is typically a bitwise-Or of the bit masks defined in the class LabelingModelEvent . For instance, when a label was removed, an event with type (STRUCTURE_CHANGED | LABEL_REMOVED) is fired and the removed label is stored in the event. The labeling model event listener mechanism provides a means to keep the layout algorithms informed of these changes. When the layout algorithm is restarted on the same graph, it is able to detect whether the data structures have changed since the last time the layout was successfully performed. If necessary the layout can be performed again. If there was no change, the layout algorithm can avoid unnecessary work by not performing the layout.
The labeling model event listener is defined by the LabelingModelListener interface. To receive the events (that is, instances of the LabelingModelEvent class), a class must implement the LabelingModelListener interface and must register itself using the addLabelingModelListener method of the IlvLabelingModel class.
Note
The label layout algorithms register themselves as listeners to the labeling model (via the functionality in IlvLabelLayout ). Therefore, there is usually no need to manipulate these listeners directly.

Storing and retrieving object properties

The following methods of the IlvLabelingModel class allow a layout algorithm to store data objects for each label or obstacle:
void setProperty(Object labelOrObstacle, String key, Object value)  
Object getProperty(Object labelOrObstacle, String key)  
void setProperty(String key, Object value)  
Object getProperty(String key)  
The layout algorithm may need to associate a set of properties with the labels or obstacles, or global properties. Properties are a set of key-value pairs, where the key is a String object and the value can be any kind of information value.