arcgissamples\scenario\toc\TocControl.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
GIS Client
arcgissamples\scenario\toc\TocControl.java
/* Copyright 2015 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions at <your ArcGIS install location>/DeveloperKit10.4/userestrictions.txt.
* 
*/
package arcgissamples.scenario.toc;

/**
 * Toc control is basically a tree control with the mapframe as root nodes
 * and layers as child nodes.
 * Each layer is displayed with a check box to toggle the visibility
 * and a label to set the layer name.
 * The hierarchy of toc control is as per the following diagram.
 *
 * *      --------------------------------------------
 *      |                                          |
 *      |  <Map Name>                              |
 *      |      |                                   |
 *      |      |----[] layer name1                 |
 *      |      |----[] layer name2                 |
 *      |                                          |
 *      |------------------------------------------|
 *
 *
 *
 *
 */
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import arcgissamples.scenario.map.LayerInfo;
import arcgissamples.scenario.map.MapComponent;
import arcgissamples.scenario.map.MapServerConnectionInfo;

public class TocControl extends JScrollPane implements MouseListener {

  private static final long serialVersionUID = 1L;
//  Renderer for tree control
  private TocTreeRenderer tocRenderer = null;
  private JTree tocTree = null;
  private MapComponent mapComponent = null;
  private MapServerConnectionInfo mapInfo = null;
  //Root tree node
  DefaultMutableTreeNode root = null;
  //Map Frame Node
  MapFrameNode mapFrameNode = null;

  public TocControl() {
    this(null);
  }

  public TocControl(MapComponent mapcomponent) {
    super();
    //Check for mapcomponent object
    if(mapcomponent != null) {
      mapComponent = mapcomponent;
      mapInfo = mapcomponent.getMapInfo();
    }
    init();
  }

  /**Method to initialize tree control.
   * Root node is hidden all the time. At first Map frame node is added to the root node
   * and the label value is set to "Layers".
   * For ex:
   *          |----------------------|
   *          | root (not shown)     |
   *          |  |                   |
   *          |  |-- <Icon> Layers   |
   *          |                      |
   *          |                      |
   *          |                      |
   *          |                      |
   *          |                      |
   *          |----------------------|
   *
   * Subsequent calls to refreshToc() will remove all the nodes from the root.
   */

  public void init() {
    root = new DefaultMutableTreeNode();
    //Create a map frame node.
    mapFrameNode = new MapFrameNode();
    mapFrameNode.setLabel("Layers");
    // Add it to the root node
    root.add(mapFrameNode);
    //Create tree control with root node as parameter
    tocTree = new JTree(root);
    //set root visibility to false
    tocTree.setRootVisible(false);
    //Hide root handles
    tocTree.setShowsRootHandles(false);
    //Only one node will be selected at any time
    tocTree.getSelectionModel().setSelectionMode(
        javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION
    );
    //Create a tree cell renderer
    tocRenderer = new TocTreeRenderer();
    //Set the cell renderer
    tocTree.setCellRenderer(tocRenderer);
    // Add mouse listener
    tocTree.addMouseListener(this);
    //Create a panel
    JPanel panel = new JPanel();
    //set layout
    panel.setLayout(new java.awt.BorderLayout());
    //Add tree control to center
    panel.add(tocTree, java.awt.BorderLayout.CENTER);
    //Make the border raised
    panel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.SoftBevelBorder.RAISED));
    //Add it to scrollpane
    getViewport().add(panel);
    //set the scrollpanes border to null to panels custom border
    setBorder(null);
  }

  /**Sets the map control
   * @param mapcomponent
   */

  public void setMapComponent(MapComponent mapcomponent) {
    mapComponent = mapcomponent;
    if(mapComponent != null)
      mapInfo = mapComponent.getMapInfo();
  }

  /**Sets the mapInfo
   * @param mapcomponent
   */

  public void setMapInfo(MapServerConnectionInfo mapInfo) {
    this.mapInfo = mapInfo;
  }


  /** Method to refresh the toc control when a new mxd document
   * is opened. First removes all the nodes from the root node.
   * For each Map object, MapFrame node is constructed first and
   * all the layers within the map object are added as child nodes.
   * A layer may itself contain a set of layers.
   * For ex:
   *      --------------------------------------------
   *      |                                          |
   *      |  <Map Name>                              |
   *      |      |                                   |
   *      |      |----[] layer name1                 |
   *      |      |----[] layer name2                 |
   *      |                                          |
   *      |------------------------------------------|
   *
   */

  public void refreshToc() {
    //Removes all the children
    root.removeAllChildren();

    try {
      //Get the count of all the maps.
      int count = mapInfo.getMapCount();
      //Create a map frame node for each map object
      for(int i = 0; i < count; i++) {
        //Get the map name
        String mapName = mapInfo.getMapName(i);
        //Create a map frame node using the map name.
        MapFrameNode mapFrameNode = new MapFrameNode(mapName);
        //Add this to root node
        root.add(mapFrameNode);
        //Get layerTable containing id and the visibility state
        Vector layerTable = mapInfo.getLayerInfo(mapName);
        //If no layers then return
        if(layerTable.isEmpty()) return;
        //Add layers
        for(int j = 0; j < layerTable.size(); j++) {
          LayerInfo layerInfo = (LayerInfo)layerTable.get(j);
          addLayerNodes(layerInfo, mapFrameNode, mapName);
        }

      }
      tocTree.setShowsRootHandles(true);
      //Fire treeStructureChanged event.
      ((DefaultTreeModel)tocTree.getModel()).nodeStructureChanged(root);

    } catch(Exception ex) {
      ex.printStackTrace();
    }
  }

  /** Method which adds all the layernodes.
   *
   */

  public void addLayerNodes(LayerInfo layerInfo, Node parent, String mapName) {
    //Get the layer node and set the parent name i.e. map name
    LayerNode layerNode = new LayerNode(layerInfo.getID(), layerInfo.getName(), mapName, layerInfo.getVisible(), true);
    layerNode.setParentMapFrame(mapName);
    //Add this to map frame.
    parent.add(layerNode);
  }

  /**Sets the layer visibility of the layer and exports the image.
   * @param layer ILayer
   * @param mapFrame String
   */


  public synchronized void exportMap(LayerNode layerNode) {
    mapInfo.activate();
    //Sets the map's layer visibility
    mapInfo.setLayerDescriptorVisibility(layerNode.getLayerID(), layerNode.getParentDataFrame(), layerNode.isVisible());
    //Export the map only if it is a focus map.
    if (mapInfo.getActiveMap().equalsIgnoreCase(layerNode.getParentDataFrame()))
      mapComponent.draw(mapInfo.getExtent());

    mapInfo.passivate();
  }


  /**Method to set the layer visibility in response to Mouse Events.
   * @see java.awt.event.MouseListener#mouseClicked
   * @param e java.awt.event.MouseEvent
   */

  public void mouseClicked(MouseEvent e) {
    //Get the tree path based on the selected row.
    int row = tocTree.getRowForLocation(e.getX(), e.getY());
    javax.swing.tree.TreePath path = tocTree.getPathForRow(row);
    if (path == null)
      return;
    //Get the selected node
    javax.swing.tree.DefaultMutableTreeNode node = (javax.swing.tree.
        DefaultMutableTreeNode) path.getLastPathComponent();

    if (node != null) {
      //Check if it is a layer node
      if (node instanceof LayerNode) {

        final LayerNode layerNode = (LayerNode) node;
        //Toggle the visibility of layer node.
        layerNode.setVisible(!layerNode.isVisible());
        //Invoke node changed event
        ( (DefaultTreeModel) tocTree.getModel()).nodeChanged(node);
        //Export the map image in a separate event thread.
        javax.swing.SwingUtilities.invokeLater( (new Runnable() {
          public void run() {
            TocControl.this.exportMap(layerNode);
          }
        }));
      }
    }
  }

  public void mousePressed(MouseEvent e) {}
  public void mouseReleased(MouseEvent e) {}
  public void mouseEntered(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}

}