ArcGIS Engine controls


In this topic


About ArcGIS Engine controls

ArcGIS Engine includes a set of reusable ArcGIS control components as prebuilt pieces of software code that provides graphic functions. The Java application programming interface (API) for ArcObjects makes these controls available to use as visual components. As a visual developer, you write code to buddy into your ArcGIS Engine application. These ArcGIS Engine controls are heavyweight Abstract Window Toolkit (AWT) components.

Initializing ArcGIS Engine controls

To successfully use ArcGIS Engine controls, the static initializer, EngineInitializer.initializeVisualBeans(), must be the first method call in the main(). Due to the initialization dependencies of ArcGIS Engine, your application is not guaranteed to function properly if its usage of EngineInitializer.initializeVisualBeans() is not correct.
When an application is initialized using the EngineInitializer.initializeVisualBeans() method, each subsequent object is automatically created and utilized in a special thread internally created to hold and service all ArcObjects components. While this behavior maintains thread safety, there is a performance impact related to the cost of marshalling ArcObjects across threads. As such, only use the initializeVisualBeans() method when working with graphical user interface (GUI) based applications.

Mixing heavy and light components

A primary development goal of the Swing architecture was that it be based on the existing AWT architecture. This allows developers to mix both kinds of components in the same application. When using ArcGIS Engine controls with other Swing components, use care while mixing the heavy and light components. For more information, see Mixing heavy and light components on the Sun Developer Network (SDN) Web site.
If using Swing components in your application, disable lightweight pop-ups where the option is available. See the following code example:
[Java]
jComboBox.setLightWeightPopupEnabled(false);
jPopupMenu.setLightWeightPopupEnabled(false);

Threading

As such, they are not inherently thread safe and must be handled with care, even when correctly initialized using the initializeVisualBeans method. To maintain data integrity, event handling and changes of state for Swing components are generally executed in a single thread (the event dispatching thread). Deadlocks can occur if you change the state of your Swing components from any thread other than the event dispatching thread.
This need for precaution is particularly important when interacting with ArcGIS Engine controls. Events fired by ArcObjects, including the ArcGIS controls, are not called in the event dispatching thread but in a separate thread. In this situation, Sun recommends that the SwingUtilities.invokeLater method be used to put the change of state operation on the event dispatching thread1. For example, if you want to change the state of a Swing component, wrap your calls in a SwingUtilities.invokeLater call. See the following code example:
[Java]
private void mapControlOnMouseDown(final IMapControlEvents2OnMouseDownEvent evt)
    throws java.io.IOException{
    Runnable r = new Runnable(){
        public void run(){
            System.out.println("Mouse clicked");
            //Show a Swing JPopupMenu.
            jPopupMenu1.show(mapBean1, evt.getX(), evt.getY());
        }
    };
    SwingUtilities.invokeLater(r);
}

Listening to events

All ArcGIS Engine controls are capable of firing events. For instance, the MapControl fires the events in the following code example:
[Java]
void onAfterDraw(IMapControlEvents2OnAfterDrawEvent theEvent){}
void onAfterScreenDraw(IMapControlEvents2OnAfterScreenDrawEvent theEvent){}
void onBeforeScreenDraw(IMapControlEvents2OnBeforeScreenDrawEvent theEvent){}
void onDoubleClick(IMapControlEvents2OnDoubleClickEvent theEvent){}
void onExtentUpdated(IMapControlEvents2OnExtentUpdatedEvent theEvent){}
void onFullExtentUpdated(IMapControlEvents2OnFullExtentUpdatedEvent theEvent){}
void onKeyDown(IMapControlEvents2OnKeyDownEvent theEvent){}
void onKeyUp(IMapControlEvents2OnKeyUpEvent theEvent){}
void onMapReplaced(IMapControlEvents2OnMapReplacedEvent theEvent){}
void onMouseDown(IMapControlEvents2OnMouseDownEvent theEvent){}
void onMouseMove(IMapControlEvents2OnMouseMoveEvent theEvent){}
void onMouseUp(IMapControlEvents2OnMouseUpEvent theEvent){}
void onOleDrop(IMapControlEvents2OnOleDropEvent theEvent){}
void onSelectionChanged(IMapControlEvents2OnSelectionChangedEvent theEvent){}
void onViewRefreshed(IMapControlEvents2OnViewRefreshedEvent theEvent){}
To add and remove listeners for the events, the controls have methods in the form addXYZEventListener and removeXYZEventListener. Adapter classes are provided as a convenience for creating listener objects. See the following code example:
[Java]
public void addIMapControlEvents2Listener(IMapControlEvents2Adapter theListener)
    throws IOException public void removeIMapControlEvents2Listener
    (IMapControlEvents2Adapter theListener)throws IOException
The following code example uses an anonymous inner class with the IMapControlEvents2Adapter to add an event listener for the onMapReplaced event to the MapControl object:
[Java]
mapControl = new MapControl();
... 
/*Wire up the events for the MapControl.*/
mapControl.addIMapControlEvents2Listener(new
    com.esri.arcgis.controls.IMapControlEvents2Adapter(){
    public void onMapReplaced
        (com.esri.arcgis.controls.IMapControlEvents2OnMapReplacedEvent e){
        try{
            IMap newMap = mapControl.getMap(); System.out.println(
                "The data frame name is: " + newMap.getName()); 

        }
        catch (IOException e1){
            e1.printStackTrace(); 
        }

    }
    );
The events fired by ArcGIS controls are custom events for which the listeners are provided. Adding listeners from the java.awt.event package, such as MouseListener, to the controls will not be helpful, as the controls do not fire those events. Instead, use similar events, such as onMouseDown, onMouseUp, and onMouseMove provided by the corresponding event listener, which in the case of MapControl, is IMapControlEvents2.
In addition, these custom events are not fired from within Java's event dispatching thread. As discussed in the Threading section, when you want to change the state of a pure Java GUI component from one of these custom events, you must do so via the SwingUtilities.invokeLater method.
However, since ArcGIS Engine controls do not run in the event dispatching thread, you can change their state directly from within any of the custom ArcGIS events. For example, you can call Map.refresh from an ITransformEventsListener without using invokeLater.

Drawing on ArcGIS Engine controls

Calling getGraphics on ArcGIS controls to obtain java.awt.Graphics or java.awt.Graphics2D objects will not work successfully. To draw on ArcGIS Engine controls, use the corresponding display objects, such as ScreenDisplay, GlobeDisplay, and so on.


See Also:

Mixing heavy and light components




Development licensingDeployment licensing
Engine Developer KitEngine
ArcGIS for Desktop Basic
ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced