arcgissamples\scenario\toc\TocControl.java
/* Copyright 2010 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. * */ 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.MapInfo; 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 MapInfo 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(); } /** 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) { //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()); } /**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) {} }