skip to main content
Programmer's documentation > Rogue Wave JViews Framework Essential Features > Managers > Managing graphic objects
 
Managing graphic objects
Describes how to assign graphic objects to a manager.
*Adding objects to a manager and removing them
*Describes how to add a graphic object to a manager and remove it, and how to find out how many objects are managed by the manager.
*Modifying geometric properties of objects
*Describes how to modify the geometric properties of objects using a manager method.
*Applying functions
*Describes how to apply a user-defined function to objects.
*Editing and selecting properties
*Describes how to specify the editing properties of an object.
*Optimizing drawing tasks
*Describes how drawing tasks can be minimized.
*Listener for the content of the manager
*Describes how to listen for changes to the content of a manager.
Adding objects to a manager and removing them
The purpose of the manager is to manage a large set of graphic objects. Each graphic object can be managed by only one manager at a time, which means that you cannot add the same graphic object to two different managers.
The following methods allow you to add a graphic object to a manager.
 
void addObject(IlvGraphic obj, int layer, boolean redraw)
 
void addObject(IlvGraphic obj, boolean redraw)
The following example creates a rectangle object and adds it to a manager:
 
IlvManager mgr = new IlvManager();
IlvGraphic obj = new IlvRectangle(new IlvRect(10,10,100,100));
mgr.addObject(obj, false);
The second addObject method does not specify the layer where the object must be inserted. The reason for this is that there is a default insertion layer which allows you to add objects without specifying the layer at every call. The initial value for the default insertion layer is 0 but it can be modified using the following methods:
 
int getInsertionLayer()
 
void setInsertionLayer(int layer)
Once an object has been added to a manager, you can remove it with:
 
void removeObject(IlvGraphic obj, boolean redraw)
You can also remove the objects from the manager or from a specific layer using one of the following methods:
 
void deleteAll(boolean redraw)
 
void deleteAll(int layer, boolean redraw)
The following method can be used to know whether a graphic object is managed by the current manager:
 
boolean isManaged(IlvGraphic obj)
You can access all the objects of the manager or of a specified layer using one of the following methods:
 
IlvGraphicEnumeration getObjects()
 
IlvGraphicEnumeration getObjects(int layer)
These methods return an IlvGraphicEnumeration object facilitating the enumeration of the contents of the manager (or layer). You may use it in the following manner:
 
IlvGraphicEnumeration objects = manager.getObjects();
IlvGraphic obj;
while(objects.hasMoreElements()) {
    obj = objects.nextElement();
    //perform some action
}
NOTE  When stepping through the contents of the manager (or layer) by means of an enumeration, you must not modify the contents of the manager by adding or removing objects or layers. Doing so may lead to unpredictable results.
Other useful methods will give you the number of objects in the manager or in a layer:
 
int getCardinal()
 
int getCardinal(int layer)
Modifying geometric properties of objects
For every operation that leads to a modification of the bounding box of a graphic object, you must use the applyToObject method of the IlvManager class. As this method notifies the manager of the modification of the bounding box, you never directly call the moveObject and reshapeObject methods of IlvGraphic:
 
void moveObject(IlvGraphic obj, float x, float y, boolean redraw)
 
void reshapeObject(IlvGraphic obj, IlvRect newrect, boolean redraw)
For these basic operations, the manager has methods that call applyToObject for you:
Example: Moving an object
The following code gets a reference to an object named test from the manager. If the object exists, it is moved to the point (10, 20) and redrawn (fourth parameter set to true ).
 
IlvGraphic object = manager.getObject("test");
if (object != null)
  manager.moveObject(object, 10, 20, true);
The moveObject method is equivalent to the following code:
 
manager.applyToObject(object,
  new IlvApplyObject()
  {
   public void apply(IlvGraphic obj, Object arg){
     IlvPoint p = (IlvPoint) arg;
     obj.move(p.x, p.y);
   }
  },
  new IlvPoint(10,20), true);
This code calls the applyToObject method with object as a parameter and an anonymous class that implements the IlvApplyObject interface. The arg parameter is an IlvPoint object that gives the new location of the object.
The method applyToObject is defined in the IlvGraphicBag interface, so you may call applyToObject directly from a graphic object using:
 
obj.getGraphicBag().applyToObject(obj, ...);
Modifying multiple graphic objects
To apply an operation to many graphic objects repeatedly, call:
 
void applyToObjects(IlvGraphicVector vector,
                      IlvApplyObject f,
                      Object arg,
                      boolean redraw)
This applies the operation specified by the IlvApplyObject f to each graphic object contained in the input vector.
To apply complex operations that affect the bounding box of many graphic objects to many objects once only, call:
 
void applyToObjects(IlvGraphicVector vector,
                      IlvApplyObjects f,
                      Object arg,
                      boolean redraw)
This applies the operation specified by the IlvApplyObjects f once only. This is useful for complex operations that affect the bounding box of many objects.
NOTE The applyToObjects method is overloaded. In the first example it takes an IlvApplyObject object as a parameter. In the second example it takes an IlvApplyObjects (plural) object as a parameter.
Applying functions
To apply a user-defined function to objects that are located either partly or wholly within a specific region, use the following IlvManager methods:
*mapInside
to apply a function to all graphic objects inside a specified rectangle.
*mapIntersects
to apply a function to all graphic objects that intersect a specified rectangle.
Editing and selecting properties
The IlvManager class contains the following methods, which allow you to control the editing and selecting properties of an object added to a manager:
*To specify whether an object can be moved:
setMovable
isMovable
*To specify whether an object can be edited:
setEditable
isEditable
*To specify whether an object can be selected:
setSelectable
 
boolean isSelectable(IlvGraphic obj)
These properties can be specified for graphic objects that are handled by an IlvSelectInteractor object. An IlvSelectInteractor object allows objects to be interactively selected in the manager, to be moved around, and to have their graphic properties edited.
Optimizing drawing tasks
A special manager feature minimizes the cost of drawing tasks to be done after geometric operations have been performed. This is useful in situations where you want to see the results of your work. This feature uses a region of invalidated parts of the display called the update region. The update region stores the appropriate regions before any modifications are carried out on objects, as well as those regions that are relevant after these modifications have been carried out for each view.
To successfully apply an applicable function, you must mark the regions where the objects are located as invalid, apply the function, and then invalidate the regions where the objects involved are now located (applying the function may change the location of the objects). This mechanism is greatly simplified by a set of methods of the IlvManager class. Regions to be updated are only refreshed when the method reDrawViews is called. This means that refreshing the views of a manager is done by marking regions to be redrawn in a cycle of initReDraws and reDrawViews.
These cycles can be nested so that only the last call to the method reDrawViews actually updates the display. The IlvManager methods that help you optimize drawing tasks are:
*initReDraws
Marks the beginning of the drawing optimization operation by emptying the region to update for each view being managed. Once this step is taken, direct or indirect calls to a draw instruction are deferred. For every initReDraws, there should be one call to reDrawViews, otherwise, a warning is issued. Calls to initReDraws can be embedded so that the actual refresh only takes place when the last call to reDrawViews is reached.
*invalidateRegion
Defines a new region as invalid, that is, this region will be redrawn later. Each call to invalidateRegion adds the region to the update region in every view.
*reDrawViews
Sends the drawing commands for the whole update region. All the objects involved in previous calls to invalidateRegion are then updated.
*abortReDraws
Aborts the mechanism of deferred redraws (for example, if you need to refresh the whole screen). This function resets the update region to empty. If needed, you should start again with an initReDraws call.
*isInvalidating
Returns true when the manager is in an initReDraws / reDrawViews state.
This mechanism is used in the applyToObject method.
In fact the call:
 
manager.applyToObject(obj, func, userArg, true);
is equivalent to:
 
manager.initReDraws();
manager.invalidateRegion(obj);
manager.applyToObject(obj, func, userArg, false);
manager.invalidateRegion(obj);
manager.reDrawViews();
The invalidateRegion method works with the bounding box of the object given as a parameter. When an operation applied to the object modifies its bounding box, invalidateRegion must be called twice: once before and once after the operation. For example, for a move operation, you must invalidate the initial region where the object was before being moved and invalidate the final region so that the object can be redrawn. In other situations, such as changing the background, only the call after the operation is necessary.
Listener for the content of the manager
When the content of the manager changes, the manager will fire a ManagerContentChangedEvent event. Any class can listen for the modification of the content of the manager by implementing the ManagerContentChangedListener interface.
This interface contains only the contentsChanged method.
 
void contentsChanged(ManagerContentChangedEvent evt)
This method is called when an object is added to or removed from the manager, or when the visibility, the bounding box, or the layer of a graphic object changes. A class that implements this interface will register itself by calling the addManagerContentChangedListener method of the manager.
A ManagerContentChangedEvent can be of several types depending on the type of modification in the manager. For each type, there is a corresponding subclass of the class ManagerContentChangedEvent. The type of the event can be retrieved with the getType method of the class. The list of these subclasses is indicated below along with the type of change in the manager that is responsible for it:
*ObjectInsertedEvent ( type OBJECT_ADDED)
A graphic object has been inserted. You can retrieve the graphic object that was inserted with the getGraphicObject method.
*ObjectRemovedEvent ( type OBJECT_REMOVED)
A graphic object has been removed. You can retrieve the graphic object that was removed with the getGraphicObject method.
*ObjectBBoxChangedEvent (type OBJECT_BBOX_CHANGED )
The bounding box of a graphic object has changed. You can retrieve the graphic object concerned using the getGraphicObject method and the old and new bounding box with the getOldBoundingBox and getNewBoundingBox methods.
*ObjectLayerChangedEvent ( type OBJECT_LAYER_CHANGED)
A graphic object has changed layers. You can retrieve the graphic object concerned using getGraphicObject and the old and new layer using the getOldLayer and getNewLayer methods.
*ObjectVisibilityChangedEvent (type OBJECT_VISIBILITY_CHANGED)
The visibility of a graphic object has changed. You can retrieve the graphic object concerned using getGraphicObject. The method isObjectVisible will tell you the new state of the object.
A listener will cast the event depending on the type:
 
public void contentsChanged(ManagerContentChangedEvent event)
{
  if (event.getType() == ManagerContentChangedEvent.OBJECT_ADDED) {
    ObjectInsertedEvent e = (ObjectInsertedEvent)event;
    IlvGraphic object = e.getGraphicObject();
    ....
  }
}
As ManagerContentChangedEvent events can be sent very often (especially when numerous objects are being added as in the case of reading a file), the manager provides a way to notify the listeners that it is currently doing a series of modifications. In this case, the event will contain a flag telling the listener that the manager is currently performing several modifications. This flag can be tested using the isAdjusting method of the ManagerContentChangedEvent class. The manager will notify the listeners of the end of a series by sending a final ManagerContentsChangedEvent of type ADJUSTMENT_END.
Thus, a listener can decide to react to global modifications, but not to all individual modifications using the following code:
 
public class MyListener implements ManagerContentsChangedListener
{
  public void contentsChanged(ManagerContentChangedEvent event)
  {
     if (!event.isAdjusting()) {
        // do something
     }
  }
}
When making numerous modifications in a manager, you may want to be able to notify the listeners in the same way. To do so, you can use the setContentsAdjusting method of the manager in the following way:
 
manager.setContentsAdjusting(true);
try {
 //add a lot of objects
} finally {
  manager.setContentsAdjusting(false);
}
All operations done between the two calls to setContentsAdjusting will fire a ManagerContentChangedEvent event with the isAdjusting flag set to true. A call to the setContentsAdjusting method with the parameter set to false can send the file ADJUSTMENT_END event.
This mechanism can also help the internal listeners of Rogue Wave JViews to work in a more efficient way, so you are recommended to use it.
Events related to imminent content changes
Since JViews 8.1, IlvManager fires events when a graphic object is about to change or about to be deleted. These events are fired before the graphic objects are changed or deleted. To listen for these events, you need to implement the following interface.
 
public interface ManagerContentMonitor
  extends ManagerContentChangedListener
{
  public void contentAboutToChange(ManagerContentAboutToChangeEvent event);
}
As this interface extends ManagerContentChangedListener, you can install a ManagerContentMonitor by calling addManagerContentChangedListener. IlvManager will call the method contentAboutToChange() that you have implemented when a graphic object is about to change or about to be deleted.

Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.