MOLE manual group draw
arcgissamples\defensesolutions\ManualGroupDraw.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.defensesolutions;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

import com.esri.arcgis.beans.map.*;
import com.esri.arcgis.beans.TOC.*;
import com.esri.arcgis.beans.toolbar.*;
import com.esri.arcgis.carto.*;
import com.esri.arcgis.controls.*;
import com.esri.arcgis.defensesolutions.*;
import com.esri.arcgis.display.*;
import com.esri.arcgis.geometry.*;
import com.esri.arcgis.system.*;

import static com.esri.arcgis.carto.esriViewDrawPhase.*;
import static com.esri.arcgis.defensesolutions.moleDeclutterOptionEnum.*;
import static com.esri.arcgis.system.esriLicenseProductCode.*;
import static com.esri.arcgis.system.esriLicenseStatus.*;


public class ManualGroupDraw extends JFrame
{
    private static final long  serialVersionUID = 1;
    private static final int[] declutterOptions = { moleDeclutterNone, moleDeclutterLeader, moleDeclutterManual, moleDeclutterStack };

    private IMapControl3       mapControl       = null;
    private IMoleGroupElement  moleGroup        = new MoleGroupElement();
    private Random             random           = new Random();

    private JPanel             jContentPane     = null;
    private ToolbarBean        toolbarBean      = null;
    private JSplitPane         jSplitPane       = null;
    private TOCBean            TOCBean          = null;
    private MapBean            mapBean          = null;
    private JPanel             toolPanel        = null;
    private JButton            btnAddGroup      = null;
    private JComboBox          cbDeclutter      = null;


    /**
     * This method initializes toolPanel
     *
     * @return javax.swing.JPanel
     */
    private JPanel getToolPanel()
    {
        if ( toolPanel == null )
        {
            GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
            gridBagConstraints3.insets = new Insets (0, 0, 0, 10);
            GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
            gridBagConstraints2.fill = GridBagConstraints.VERTICAL;
            gridBagConstraints2.weightx = 0.0;
            GridBagConstraints gridBagConstraints = new GridBagConstraints();
            gridBagConstraints.gridx = 0;
            gridBagConstraints.ipadx = 0;
            gridBagConstraints.anchor = GridBagConstraints.WEST;
            gridBagConstraints.weightx = 1.0;
            gridBagConstraints.insets = new Insets (0, 0, 0, 0);
            gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
            gridBagConstraints.gridy = 0;
            toolPanel = new JPanel();
            toolPanel.setLayout (new GridBagLayout());
            toolPanel.add (getToolbarBean(), gridBagConstraints);
            toolPanel.add (getBtnAddGroup(), gridBagConstraints3);
            toolPanel.add (getCbDeclutter(), gridBagConstraints2);
        }
        return toolPanel;
    }


    /**
     * This method initializes btnAddGroup
     *
     * @return javax.swing.JButton
     */
    private JButton getBtnAddGroup()
    {
        if ( btnAddGroup == null )
        {
            btnAddGroup = new JButton();
            btnAddGroup.setText ("Add Group Element");
            btnAddGroup.addActionListener (new ActionListener() {
                public void actionPerformed (ActionEvent e) {
                    ManualGroupDraw.this.addGroup();
                }
            });
        }
        return btnAddGroup;
    }


    /**
     * This method initializes cbDeclutter
     *
     * @return javax.swing.JComboBox
     */
    private JComboBox getCbDeclutter()
    {
        if ( cbDeclutter == null )
        {
            cbDeclutter = new JComboBox();
            cbDeclutter.addItem ("No Decluttering");
            cbDeclutter.addItem ("Leader Decluttering");
            cbDeclutter.addItem ("Manual Decluttering");
            cbDeclutter.addItem ("Stack Decluttering");
            cbDeclutter.setLightWeightPopupEnabled (false);
            cbDeclutter.setEnabled (false);
            cbDeclutter.addActionListener (new java.awt.event.ActionListener() {
                public void actionPerformed (java.awt.event.ActionEvent e) {
                    ManualGroupDraw.this.changeDeclutter();
                }
            });
        }
        return cbDeclutter;
    }


    /**
     * This method initializes jSplitPane
     *
     * @return javax.swing.JSplitPane
     */
    private JSplitPane getJSplitPane()
    {
        if ( jSplitPane == null )
        {
            jSplitPane = new JSplitPane();
            jSplitPane.setDividerLocation (150);
            jSplitPane.setDividerSize (2);
            jSplitPane.setRightComponent (getMapBean());
            jSplitPane.setLeftComponent (getTOCBean());
        }
        return jSplitPane;
    }


    /**
     * This method initializes TOCBean
     *
     * @return com.esri.arcgis.beans.TOC.TOCBean
     */
    private TOCBean getTOCBean()
    {
        if ( TOCBean == null )
        {
            TOCBean = new TOCBean();
            try { TOCBean.setBuddyControl (getMapBean()); }
            catch ( IOException e ) { e.printStackTrace(); }
        }
        return TOCBean;
    }


    /**
     * This method initializes mapBean
     *
     * @return com.esri.arcgis.beans.map.MapBean
     */
    private MapBean getMapBean()
    {
        if ( mapBean == null )
            mapBean = new MapBean();
        return mapBean;
    }


    /**
     * This method initializes this
     *
     * @return void
     */
    private void initialize()
    {
        this.setSize (800, 600);
        this.setContentPane (getJContentPane());
        this.setTitle ("MOLE Manual Group Draw");
        this.addWindowListener (new WindowAdapter() {
            public void windowClosing (WindowEvent e) {
                try { new AoInitialize().shutdown(); }
                catch ( Exception x ) { x.printStackTrace(); }
            }
        });
    }


    /**
     * This method initializes jContentPane
     *
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane()
    {
        if ( jContentPane == null )
        {
            jContentPane = new JPanel();
            jContentPane.setLayout (new BorderLayout());
            jContentPane.add (getJSplitPane(), BorderLayout.CENTER);
            jContentPane.add (getToolPanel(), BorderLayout.NORTH);
        }
        return jContentPane;
    }


    /**
     * This method initializes toolbarBean
     *
     * @return com.esri.arcgis.beans.toolbar.ToolbarBean
     */
    private ToolbarBean getToolbarBean()
    {
        if ( toolbarBean == null )
        {
            toolbarBean = new ToolbarBean();
            toolbarBean.setItemsString ("5|controls/ControlsOpenDocCommand|0|-1|0|0|1;5|controls/ControlsAddDataCommand|0|-1|0|0|1;5|controls/ControlsSaveAsDocCommand|0|-1|0|0|1;11|controls/ControlsMapZoomPanTool|0|-1|0|0|1;11|controls/ControlsMapFullExtentCommand|0|-1|0|0|1;11|controls/ControlsMapZoomToLastExtentBackCommand|0|-1|0|0|1;11|controls/ControlsMapZoomToLastExtentForwardCommand|0|-1|0|0|1;11|controls/ControlsMapZoomToolControl|0|-1|0|0|1;8|controls/ControlsSelectTool|0|-1|0|0|1;11|controls/ControlsMapGoToCommand|0|-1|0|0|1;10|controls/ControlsMapIdentifyTool|0|-1|0|0|1;10|controls/ControlsMapMeasureTool|0|-1|0|0|1");
            try { toolbarBean.setBuddyControl (getMapBean()); }
            catch ( IOException e ) { e.printStackTrace(); }
        }
        return toolbarBean;
    }


    private static void initializeArcGISLicenses()
    {
        try
        {
            AoInitialize ao = new AoInitialize();
            if ( ao.isProductCodeAvailable(esriLicenseProductCodeEngine) == esriLicenseAvailable )
                ao.initialize (esriLicenseProductCodeEngine);
            else {
              System.err.println( "Could not initialize an ArcGIS Engine license. Exiting application.");
                System.exit(-1);
            }
        }
        catch ( Exception e ) { e.printStackTrace(); }
    }


    /** Program entry point
     * @param args
     */
    public static void main(String[] args)
    {
        try
        {
            EngineInitializer.initializeVisualBeans();
            ManualGroupDraw mapTocToolbar = new ManualGroupDraw();
            mapTocToolbar.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            mapTocToolbar.setVisible (true);
        }
        catch ( Exception e ) { e.printStackTrace(); }
    }


    /**
     * This is the default constructor
     */
    public ManualGroupDraw()
        throws IOException
    {
        super();
        initializeArcGISLicenses();
        initialize();

        // try to load a default map document
        String arcgisHome = null;
      String dataPath = null;

      arcgisHome = System.getenv("AGSDEVKITJAVA");
        if (arcgisHome == null)
        {
            JOptionPane.showInputDialog("AGSDEVKITJAVA environment variable is not set, exiting application");
            System.exit(-1);
        }

        dataPath = arcgisHome + File.separator + "java" + File.separator +
          "samples" + File.separator + "data" + File.separator + "mole" + File.separator +
          "mole_base.mxd";

        mapBean.loadMxFile( dataPath, null, null);

        mapControl = (IMapControl3) mapBean.getObject();
        cbDeclutter.setSelectedIndex (0);
    }


    private void addGroup()
    {
        try
        {
            // tell the user that we are busy for a few seconds, and don't let them press the button again
            Cursor oldCursor = getCursor();
            setCursor (Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            btnAddGroup.setEnabled (false);
            cbDeclutter.setEnabled (true);

            // tell MOLE to leave it cluttered, for now
            moleGroup.setDeclutterOption (moleDeclutterNone);
            moleGroup.setEnableDeclutter (false);

            // generate some elements (vary the number of elements as much as desired)
            IPoint point = new com.esri.arcgis.geometry.Point();
            IGroupElement groupElement = (IGroupElement) moleGroup;
            for ( int i = 0; i < 10; ++i )
            {
                // create a MarkerElement with a MOLE symbol
                IMoleSymbol moleSymbol = new MoleMarkerSymbol();
                moleSymbol.setSymbolID (DemoSymbols.getSIC(i));
                IMarkerElement markerElement = new MarkerElement();
                markerElement.setSymbol ((IMarkerSymbol)moleSymbol);
                IElement element = (IElement) markerElement;

                // add the element to the group at a random clustered location
                point.putCoords (dRandom(-15, 15), dRandom(-15, 15));
                element.setGeometry ((IGeometry)point);
                groupElement.addElement (element);
            }
            // add the group to the map and update the view
            mapControl.getActiveView().getGraphicsContainer().addElement ((IElement)moleGroup, 0);
            mapControl.getActiveView().partialRefresh (esriViewGraphics, null, null);

            // tell the user that we are no longer busy
            setCursor (oldCursor);
        }
        catch ( Exception e ) { e.printStackTrace(); }
    }


    private void changeDeclutter()
    {
        if ( ! cbDeclutter.isEnabled() ) return;
        try
        {
            // get the selected option from the combo box
            int index = cbDeclutter.getSelectedIndex();
            int option = moleGroup.getDeclutterOption();
            if ( index >= 0 && index < declutterOptions.length )
                option = declutterOptions[cbDeclutter.getSelectedIndex()];
            if ( option != moleGroup.getDeclutterOption() )
            {
                // the option has changed - set the new option and recalculate if necessary
                moleGroup.setDeclutterOption (option);
                moleGroup.setEnableDeclutter (option != moleDeclutterNone);
                IGroupElement groupElement = (IGroupElement) moleGroup;
                if ( option == moleDeclutterManual && groupElement.getElementCount() > 0 )
                {
                    // calculate the decluttered positions manually - in decimal degrees
                    double xStep = 25;
                    double xDeclutter = -0.5 * groupElement.getElementCount() * xStep;
                    if ( xDeclutter < -180 )
                    {
                        // don't fall off the end of the world
                        xStep = 360 / groupElement.getElementCount();
                        xDeclutter = -180 - 0.5 * xStep;
                    }
                    else
                        xDeclutter -= 0.5 * xStep;
                    IPoint point = new com.esri.arcgis.geometry.Point();
                    IMoleDeclutterElement moleDeclutterElement = (IMoleDeclutterElement) moleGroup;
                    for ( int i = 0; i < groupElement.getElementCount(); ++i )
                    {
                        // set a declutter point for each element
                        // these lines of code have no effect in stack or leader mode
                        IElement element = groupElement.getElement (i);
                        xDeclutter += xStep;
                        point.putCoords (xDeclutter, 45);
                        moleDeclutterElement.declutterElement (element, (IGeometry)point);
                    }
                }
                // update the display
                mapControl.getActiveView().partialRefresh (esriViewGraphics, null, null);
            }
        }
        catch ( Exception x ) { x.printStackTrace(); }
    }


    private double dRandom (double low, double high)
    {
        // generate a random floating-point number within the indicated range [low, high)
        return low + random.nextDouble() * (high - low);
    }
} // @jve:decl-index=0:visual-constraint="10,10"