Rendering dynamic content with dynamic layers


Summary This walkthrough shows you the basic steps required to create a dynamic layer that renders dynamic content. The dynamic content in this walkthrough is a simple marker that is created at a random location on the current map extent. The location of the marker is updated every 30ms and the dynamic layer is redrawn to visualize its new location.

In this topic


Create a stand-alone MapControl application

Create a simple engine application with basic and map navigation tools using the ArcGIS plug-in template for the Eclipse integrated development environment (IDE). For more information, see How to get started with templates.
See the following screen shot that shows a MapControl application:
 

Create a custom command that enables dynamic display mode

Do the following to implement a custom command by extending the ArcGIS Engine BaseCommand class:
  1. Create a Java class—ToggleDynamicDisplayCommand—that extends the BaseCommand class.
  2. Set the command properties. In the class constructor, set the class members that define command properties, such as name, caption, ToolTip, and so on. See the following code example:
[Java]
public ToggleDynamicDisplayCommand(){

    this.category = "Toggle dynamic display";
    this.caption = "Toggle dynamic mode";
    this.message = "Toggle dynamic mode on and off";
    this.toolTip = "Toggle dynamic mode";
    this.name = "MyDynamicDisplayApp_ToggleDynamicDisplayCmd";
    this.enabled = true;
}
  1. Add class variables for HookHelper and IDynamicMap. See the following code example: 
[Java]
private HookHelper hookHelper = null;
private IDynamicMap dynamicMap = null;
  1. Override the onCreate() method. When the command is created, set the hook by initializing it to the passed reference. See the following code example:
[Java]
@Override public void onCreate(Object arg){
    if (arg == null)
        return ;
    try{
        hookHelper = new HookHelper();
        hookHelper.setHookByRef(arg);
    }
    catch (IOException e){
        System.out.println("Exception:ToggleDynamicDisplay#onCreate");
        e.printStackTrace();
    }
}
  1. Override the onClick method. When the command is clicked, verify the focus map supports the dynamic map. Set the dynamic display draw rate (in milliseconds) and toggle dynamic mode. See the following code example:
[Java]
@Override public void onClick(){
    try{
        // Cast into dynamic map. 
        dynamicMap = (IDynamicMap)hookHelper.getFocusMap();

        //Switch in and out of dynamic mode.
        if (dynamicMap.isDynamicMapEnabled()){
            dynamicMap.setDynamicMapEnabled(false);
        }
        else{
            dynamicMap.setDynamicMapEnabled(true);
        }
    }
    catch (IOException e){
        System.out.println("Exception:ToggleDynamicDisplay#onClick");
        e.printStackTrace();
    }
}
  1. Override the command's isChecked() method to indicate if the map is in dynamic display mode. This displays the command as "pushed in" when the map is in dynamic display mode. See the following code example:
[Java]
@Override public boolean isChecked(){
    boolean dynamicMode = true;
    if (dynamicMap == null)
        return false;
    try{
        dynamicMode = dynamicMap.isDynamicMapEnabled();
    }
    catch (IOException e){
        System.out.println("Exception:ToggleDynamicDisplay#isChecked");
        e.printStackTrace();
    }
    return dynamicMode;
}
  1. Add the command onto the application toolbar by adding the following code example to the getToolbarBean() method in the created simple map application class. Add the out-of-the box Add Data command to access ArcGIS Online maps and the Roam tool. See the following code example:
[Java]
toolbarBean.addItem(ControlsAddDataCommand.getClsid(), 0,  - 1, false, 0,
    esriCommandStyles.esriCommandStyle esriCommandStyleIconAndText);
toolbarBean.addItem(ControlsMapRoamTool.getClsid(), 0,  - 1, false, 0,
    esriCommandStyles.esriCommandStyleIconAndText);
toolbarBean.addItem(new ToggleDynamicDisplayCommand(), 0, 0, false, 0,
    esriCommandStyles.esriCommandStyleTextOnly);

Test the application

To test the application, add data from ArcGIS Online services. For more information about ArcGIS Online, see http://arcgisonline.esri.com.
  1. Launch the map application in the Eclipse IDE.
  2. Click Add Data and click the Servers category on the Add Data dialog box.
  3. Click ArcGIS on services.arcgisonline.com on the Add Data dialog box.
  4. Click I3_Imagery_Prime_World_2D under the Elevation node, then click Open to add the ArcGIS server layer to the map. See the following screen shot:


  1. Click your custom—Toggle dynamic mode—command to switch to dynamic display mode.
  2. Zoom, pan, and roam the map. Experiment with the Continuous Pan and Zoom tool.
  3. When done, toggle off dynamic mode. See the following screen shot:

In dynamic mode, there are no blank envelopes as you pan the map. When you zoom or pan to a new location, the map initially displays at a coarse resolution and refines it gradually. 

Persist the dynamic display cache by saving the map document

To persist the cache that dynamic display creates for each layer, save your map or alternatively, save individual layers as layer files.
  1. In your application, click Save As on the toolbar.
  2. Save the map locally as MyDynamicDisplayDoc.mxd.
  3. Shut down and rerun the application. 
  4. Click Open Document on the toolbar. Browse to the document you saved earlier and open it.
  5. Click Toggle dynamic mode on the application toolbar to switch to dynamic mode (this time the data loads almost immediately).
  6. Pan and zoom to areas that you used in the Test the application section. Each tile you previously viewed loads almost immediately.
  7. Close the application.
When you enable dynamic display, it creates a separate cache for each layer on your map. To reuse the cache on the next session of your application, enable dynamic mode once, then save your map as a map document, or save individual layers as layer files.

Implement a dynamic layer

Do the following to create a simple dynamic layer; the dynamic layer draws from a simulated dynamic feed:
  1. Create a Java class—MyDynamicLayer.java—that implements IDynamicLayer, ILayer, and IGeoDataset.
    • The class also implements the Runnable interface to create a simple thread that can make the layer dirty at regular intervals (30ms) and redraw the layer. The thread sleeps for 30ms and wakes up to set the dirty property of the layer. In real life scenarios, the dirty property is set to true when you need to update your dynamic items. It can be managed by a thread or as an event that gets fired while listening to an external feed that commands the update of the dynamic layer.
  2. Override the ILayer's interface getter and setter methods for the layers name property. See the following code example:
[Java]
public class MyDynamicLayer implements IDynamicLayer, ILayer, IGeoDataset, Runnable{

    //Define the layer name.
    private String layerName = "";

    public MyDynamicLayer(){
        try{

            //Set the layer name.
            this.setName("Dynamic Layer");

            Thread dirtyFlagThread = new Thread(this);
            dirtyflagThread.start();

        }
        catch (Exception e){
            System.out.println("Exception in MyDynamicLayer#Constructor");
            e.printStackTrace();
        }
    }

    public void run(){
        try{
            while (true){
                this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate,
                    true);
                Thread.sleep(30);
            }
        }
        catch (Exception e){
            System.out.println("Exception in MyDynamicLayer#run");
            e.printStackTrace();
        }
    }

    @Override public String getName()throws IOException, AutomationException{
        return name;
    }

    @Override public void setName(String arg0)throws IOException,
        AutomationException{
        name = arg0;
    }
}
  1. Override the IDynamicLayer.drawDynamicLayer() method. The drawDynamicLayer() method draws a simple marker symbol on a point location using the dynamic display drawing application programming interfaces (APIs). The point location is a random point that is step incremented every time the drawDynamicLayer() method is invoked. In a typical scenario, the drawDynamicLayer() method renders the dynamic items on its current location using the dynamic display drawing APIs or OpenGL APIs. The following substeps describe the implementation of the drawDynamicLayer() method:
The IDynamicLayer.drawDynamicLayer() method is invoked by the dynamic display (DD) framework every time the layer needs to be rendered in the immediate or compiled phase.
[Java]

@Override public void drawDynamicLayer(int dynamicDrawPhase, IDisplay display,
    IDynamicDisplay dynamicDisplay){}
    1. Ensure the layer is valid and visible. Implement and use the ILayer.isValid() and ILayer.isVisible() method. See the following code example:
[Java]
@Override public void drawDynamicLayer(int dynamicDrawPhase, IDisplay display,
    IDynamicDisplay dynamicDisplay){
    //If the layer is not valid or visible.
    if (!(this.isValid()) || !(this.isVisible()))
    return 

}
    1. Ensure the input draw phase is immediate (esriDDPImmediate). The dynamic layer is drawn in immediate mode because it requires a subsecond refresh rate. The phase in which the drawDynamicLayer() method is invoked can be determined by checking its first argument. See the following code example:  
Dynamic drawing methods have two supported draw phases—compiled and immediate—(esriDDPCompiled and esriDDPImmediate). The drawDynamicLayer() method is called in both phases depending on the scenario. Ensure your layer is only drawing in one of the two draw phases; otherwise, your layer draws twice on each drawing cycle.
See the following code example:
[Java]
@Override public void drawDynamicLayer(int dynamicDrawPhase, IDisplay display,
    IDynamicDisplay dynamicDisplay){
    //Step 3.a. If the layer is not valid or visible.
    if (!(this.isValid()) || !(this.isVisible()))
    return 
    //Step 3.b. Check for the phase.
        if (dynamicDrawPhase != esriDynamicDrawPhase.esriDDPImmediate)
            return ;
}
    1. Get the visible extent to find a random location on the visible extent to draw the marker.
    2. Declare class variables for IDynamicGlyphFactory and IDynamicSymbolProperties2 and perform a one-time initialization. Create a glyph from a marker using IDynamicGlyphFactory.
    3. Set the initial position and the step increments for the dynamic item.
Execute the preceding Step 3.d. and Step 3.e. only once, since the subsequent calls to the drawDynamicLayer() method can use the existing class member variables (ensured by using the Boolean bOnce variable). Declare bOnce has a class variable and is set to true. See the following code example:
Creating dynamic glyphs using white as the color allows you to save resources and gain performance by reusing the same glyph over and over again. You can color the dynamic glyph to any color using IDynamicSymbolProperties2.setColor() and scale the dynamic glyph using IDynamicSymbolProperties2.setScale().
[Java]

//Step 3.c. Get the current envelope.                           
IEnvelope visibleExtent = display.getDisplayTransformation().getFittedBounds();
//Need to do it only once to avoid reinitializing variables
if (bOnce){

    //Step 3.d. Create a simple glyph from a marker symbol.

    try{
        dynamicGlyphFactory = dynamicDisplay.getDynamicGlyphFactory();
        dynamicSymbolProps = (IDynamicSymbolProperties2)dynamicDisplay;

        //Create a marker symbol.
        ICharacterMarkerSymbol markerSymbol = new CharacterMarkerSymbol();
        markerSymbol.setSize(25.0);
        //Set the symbol color to white.
        RgbColor color = new RgbColor();
        color.setRGB(0xFFFFFF);
        markerSymbol.setColor(color);
        markerSymbol.setCharacterIndex(92);
        //Create the dynamic glyph.
        markerGlyph = dynamicGlyphFactory.createDynamicGlyph((ISymbol)markerSymbol);

    }
    catch (Exception e){
        System.out.println("Exception in MyDynamicLayer#CreatingGlyph");
        e.printStackTrace();
    }

    //Step 3.e. Initialize the dynamic item's random initial position and define the step increments.
    Random r = new Random();
    double X = visibleExtent.getXMin() + r.nextDouble() * visibleExtent.getWidth();
    double Y = visibleExtent.getYMin() + r.nextDouble() * visibleExtent.getHeight();
    stepX = visibleExtent.getWidth() / 250;
    stepY = visibleExtent.getHeight() / 250;

    //Create a point location to draw.
    point = new Point();
    point.putCoords(X, Y);

    //Set the bOnce value to false.
    bOnce = false;
}
    1. Draw the dynamic element using the created glyph. Each time the dynamic display calls the layer's drawDynamicLayer() method, it redraws the dynamic items if it is using the immediate draw phase. Since dynamic display is a state machine, each time before drawing, set the dynamic symbol. In the case of a marker symbol, set the dynamic glyph and the symbol's color and scale. Finally, invoke the IDynamicDisplay.drawMarker() method to draw the marker symbol on the specified point location. See the following code example:
The IDynamicDisplay.drawXXX() method can be invoked to draw dynamic markers, multiple markers, lines, multiple lines, polylines, polygons, rectangles, and text.
[Java]
//Step 3.f. Define properties and draw the marker symbol.
dynamicSymbolProps.setDynamicGlyphByRef((esriDynamicSymbolType.esriDSymbolMarker),
    markerGlyph);
//Set the glyph's color.
dynamicSymbolProps.setColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f,
    0.0f, 1.0f);
//Set the glyph's scale.
dynamicSymbolProps.setScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f);
//Draw the marker symbol on the given point.
dynamicDisplay.drawMarker(point);
    1. Update the dynamic item. In the following code example, use synthetic information that simulates a dynamic data feed to update the location of the dynamic item. In a typical scenario, the metadata or location of the dynamic items are obtained from external sources and updated.
[Java]
//Step 3.g. Update the point location for the next draw cycle.                            
point.setX(point.getX() + stepX);
point.setY(point.getY() + stepY);

//Ensure the point falls within the visible extent.
if (point.getX() > visibleExtent.getXMax())
    stepX =  - Math.abs(stepX);
if (point.getX() < visibleExtent.getXMin())
    stepX = Math.abs(stepX);
if (point.getY() > visibleExtent.getYMax())
    stepY =  - Math.abs(stepY);
if (point.getY() < visibleExtent.getYMin())
    stepY = Math.abs(stepY);
    1. Set the layer's dirty flag to signal the dynamic display that the layer has been updated and does not need to redraw in the subsequent draw cycles until notified by the dirty flag. See the following code example:
Since the updated information is rendered, set the dirty flag to false according to the draw phase that your dynamic layer supports. Failure to do so, causes the dynamic layer to be rendered in every subsequent draw cycle.
[Java]
//Step 3.h. Set the dirty flag to false to stop the drawing in the immediate phase.
setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate, false);
The following code example shows the complete drawDynamicLayer() method:
[Java]
@Override public void drawDynamicLayer(int dynamicDrawPhase, IDisplay display,
    IDynamicDisplay dynamicDisplay){
    //Step 3.a. If the layer is not valid or visible.
    if (!(this.isValid()) || !(this.isVisible()))
    return 
    //Step 3.b. Check for the phase.
        if (dynamicDrawPhase != esriDynamicDrawPhase.esriDDPImmediate)
            return ;
    //Step 3.c. Get the current envelope.                           
    IEnvelope visibleExtent = display.getDisplayTransformation().getFittedBounds();
    //Need to do it only once to avoid reinitializing variables.
    if (bOnce){

        //Step 3.d. Create a simple glyph from a marker symbol.

        try{
            dynamicGlyphFactory = dynamicDisplay.getDynamicGlyphFactory();
            dynamicSymbolProps = (IDynamicSymbolProperties2)dynamicDisplay;

            //Create a marker symbol.
            ICharacterMarkerSymbol markerSymbol = new CharacterMarkerSymbol();
            markerSymbol.setSize(25.0);
            //Set the symbol color to white.
            RgbColor color = new RgbColor();
            color.setRGB(0xFFFFFF);
            markerSymbol.setColor(color);
            markerSymbol.setCharacterIndex(92);
            //Create the dynamic glyph.
            markerGlyph = dynamicGlyphFactory.createDynamicGlyph((ISymbol)
                markerSymbol);

        }
        catch (Exception e){
            System.out.println("Exception in MyDynamicLayer#CreatingGlyph");
            e.printStackTrace();
        }

        //Step 3.e. Initialize the dynamic item's random initial position and define the step increments.
        Random r = new Random();
        double X = visibleExtent.getXMin() + r.nextDouble() * visibleExtent.getWidth
            ();
        double Y = visibleExtent.getYMin() + r.nextDouble() *
            visibleExtent.getHeight();
        stepX = visibleExtent.getWidth() / 250;
        stepY = visibleExtent.getHeight() / 250;

        //Create a point location to draw.
        point = new Point();
        point.putCoords(X, Y);

        //Set the bOnce value to false.
        bOnce = false;
    }


    //Step 3.f. Draw the marker symbol.
    dynamicSymbolProps.setDynamicGlyphByRef((esriDynamicSymbolType.esriDSymbolMarker)
        , markerGlyph);
    //Set the glyph's color.
    dynamicSymbolProps.setColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f,
        0.0f, 1.0f);
    //Set the glyph's scale.
    dynamicSymbolProps.setScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f);
    //Draw the marker symbol on the given point.
    dynamicDisplay.drawMarker(point);

    //Step 3.g. Update the point location for the next draw cycle.                            
    point.setX(point.getX() + stepX);
    point.setY(point.getY() + stepY);

    //Ensure the point falls within the visible extent.
    if (point.getX() > visibleExtent.getXMax())
        stepX =  - Math.abs(stepX);
    if (point.getX() < visibleExtent.getXMin())
        stepX = Math.abs(stepX);
    if (point.getY() > visibleExtent.getYMax())
        stepY =  - Math.abs(stepY);
    if (point.getY() < visibleExtent.getYMin())
        stepY = Math.abs(stepY);

    //Step 3.h. Set the dirty flag to false to stop the drawing in the immediate phase.
    setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate, false);


}
  1. The following are the other methods for IDynamicLayer that need to be implemented:
    1. The IDynamicLayer.getDynamicRecompileRate() is called by the DD framework to determine the compiled phase recompile rate. By default, the value is –1; however, since the drawDynamicLayer is implemented for the immediate draw phase in this application, the recompile rate is not very significant for this specific scenario.
    2. The IDynamicLayer.setDynamicLayerDirty method sets the layer's dirty property. Two Boolean class variables (isDirtyImmediate and isDirtyCompiled) are declared to specify the draw phases.
    3. The IDynamicLayer.isDynamicLayerDirty() method is called by the DD framework to determine whether the specified layer is dirty and needs to be redrawn in the subsequent draw cycle. Depending on the draw phase, the Boolean variable (isDirtyImmediate or isDirtyCompiled) is returned. See the following code example:
[Java]
//Define required class variables.
boolean isDirtyImmediate;
boolean isDirtyCompiled;
private int recompileRate;

//Step 4.a.
public int getDynamicRecompileRate()throws IOException, AutomationException{
    return this.recompileRate;
}

//Step 4.b.
public void setDynamicLayerDirty(int phase, boolean dirtyFlag)throws IOException,
    AutomationException{
    if (phase == esriDynamicDrawPhase.esriDDPImmediate)
        isDirtyImmediate = dirtyFlag;
    else
        isDirtyCompiled = dirtyFlag;
}

//Step 4.c.
public boolean isDynamicLayerDirty(int drawPhase)throws IOException,
    AutomationException{
    if (drawPhase == esriDynamicDrawPhase.esriDDPImmediate)
        return isDirtyImmediate;
    else
        return isDirtyCompiled;
}
  1. Depending on the application scenario, implement the other methods for ILayer and IGeoDataset. For the specific application, they are less significant and are not implemented. See the following code example:
[Java]
//Class variables. 
IEnvelope extent = null;
ISpatialReference spatialRef = null;
boolean isCached = false;
boolean isValid, isVisible = true;
double maximumScale, minimumScale = 0;
boolean showTips = false;



public boolean isValid()throws IOException, AutomationException{
    return true;
}

public double getMinimumScale()throws IOException, AutomationException{
    return minimumScale;
}

public void setMinimumScale(double arg0)throws IOException, AutomationException{
    minimumScale = arg0;
}

public double getMaximumScale()throws IOException, AutomationException{
    return maximumScale;
}

public void setMaximumScale(double arg0)throws IOException, AutomationException{
    maximumScale = arg0;
}

public boolean isVisible()throws IOException, AutomationException{
    return isVisible;
}

public void setVisible(boolean arg0)throws IOException, AutomationException{
    isVisible = arg0;
}

public boolean isShowTips()throws IOException, AutomationException{
    return showTips;
}

public void setShowTips(boolean arg0)throws IOException, AutomationException{
    showTips = arg0;
}

public boolean isCached()throws IOException, AutomationException{
    return isCached;
}

public void setCached(boolean arg0)throws IOException, AutomationException{
    isCached = arg0;
}

public void setSpatialReferenceByRef(ISpatialReference arg0)throws IOException,
    AutomationException{
    spatialRef = arg0;
}

public ISpatialReference getSpatialReference()throws IOException,
    AutomationException{
    return spatialRef;
}

public IEnvelope getExtent()throws IOException, AutomationException{
    return extent;
}

public IUID getID()throws IOException, AutomationException{
    return null;
}

public void load(IVariantStream arg0)throws IOException, AutomationException{
    //Not supported in Java.
}

public void save(IVariantStream arg0)throws IOException, AutomationException{
    //Not supported in Java.
}

public IEnvelope getAreaOfInterest()throws IOException, AutomationException{
    return extent;
}

public double getLastMinimumScale()throws IOException, AutomationException{
    return 0;
}

public double getLastMaximumScale()throws IOException, AutomationException{
    return 0;
}

public String ILayerGeneralProperties_getLayerDescription()throws IOException,
    AutomationException{
    return null;
}

public void setLayerDescription(String arg0)throws IOException, AutomationException{}
public String getTipText(double arg0, double arg1, double arg2)throws IOException,
    AutomationException{
    return null;
}

public int getSupportedDrawPhases()throws IOException, AutomationException{
    return esriDrawPhase.esriDPAnnotation;
}

public void draw(int arg0, IDisplay arg1, ITrackCancel arg2)throws IOException,
    AutomationException{}

Implement a command to add the dynamic layer

Since a dynamic layer is a custom layer, write code to load it to the map. Write a custom command (AddDynamicLayerCommand) as previously specified. For more information, see Create a custom command that enables dynamic display mode in this walkthrough.
  1. In the class constructor, set the command properties. 
  2. Override the onCreate() method.
  3. Override the isEnabled() method. See the following code example:
[Java]
// Step 1. Class constructor.
public LoadDynamicLayerCommand(){

    this.category = "Add Dynamic Layer";
    this.caption = "Add Dynamic Layer";
    this.message = "Add Dynamic Layer";
    this.toolTip = "Add Dynamic Layer";
    this.name = "MyDynamicDisplayApp_AddDynamicLayerCmd";
    this.enabled = true;
}

//Step 2. Override the onCreate method.
@Override public void onCreate(Object arg){
    if (arg == null)
        return ;
    try{
        hookHelper = new HookHelper();
        hookHelper.setHookByRef(arg);
    }
    catch (Exception e){
        System.out.println("Exception:AddDynamicLayerCmd#onCreate");
        e.printStackTrace();
    }
}


//Step 3. Override the isEnabled() method.
// The command is enabled only when the map is in dynamic mode.

public boolean isEnabled(){
    boolean dynamicMode = true;
    try{
        map = (Map)hookHelper.getFocusMap();
        dynamicMap = (IDynamicMap)map;
        if (dynamicMap == null)
            return false;
        dynamicMode = dynamicMap.isDynamicMapEnabled();
    }
    catch (Exception e){
        System.out.println("Exception:AddDynamicLayerCmd#isEnabled");
        e.printStackTrace();
    }
    return dynamicMode;
}
  1. Override the onClick method to load the dynamic layer to the map.
    • Verify the map's current focus supports that dynamic display is enabled; otherwise, there is no point in loading your dynamic layer, since it will not draw in standard mode. See the following code example:
[Java]
public void onClick(){
    try{
        map = (Map)hookHelper.getFocusMap();
        if (map.isDynamicMapEnabled()){
            //Instantiate the dynamic layer and add it.
            MyDynamicLayer layer = new MyDynamicLayer();
            map.addLayer(layer);
        }
        else{
            System.out.println("Dynamic Map not enabled");

        }
    }
    catch (Exception e){
        System.out.println("Exception in AddDynamicLayerCmd#onClick");
        e.printStackTrace();
    }
}
  1. Add the custom command onto the application toolbar by adding the following code example to the getToolbarBean() method in the created simple map application class:
[Java]
toolbarBean.addItem(new AddDynamicLayerCommand(), 0, 0, false, 0,
    esriCommandStyles.esriCommandStyleTextOnly);

Run the completed application

  1. Run the Java application (in the Eclipse IDE, right-click the app class and click Run As Application).
  2. Click the Open command and add a .mxd document. Click Toggle Dynamic Display to set the map in dynamic mode.
  3. Click Add Dynamic Layer to add the dynamic layer to the map.
    • A layer (dynamic layer) is added to the table of contents (TOC) and a red star bounces back and forth on the map. 
    • When done, toggle off dynamic mode and close the application. See the following screen shot:



See Also:

Best practices for using dynamic display
Sample: Rendering dynamic content with dynamic layers
Dynamic Drawing APIs
Dynamic Map Events




Development licensing Deployment licensing
Engine Developer Kit Engine Runtime