Select graphics

Download Sample Viewer

Description

This sample shows how to select graphics in a mixed geometry graphics layer - clicking an unselected graphic will toggle it to its selected state and vice-versa. The default selection color is cyan, and it can be changed by using the setSelectionColor method on the graphics layer. A HitTestOverlay is used to obtain the clicked graphics whenever a selection has been made.

Code snippet


    // set the selection color for the graphics layer
    graphicsLayer.setSelectionColor(Color.YELLOW);

    // implement the logic to toggle graphics' selection state
    class GraphicSelectedListener implements HitTestListener {
      @Override
      public void featureHit(HitTestEvent event) {
        // get hit graphics
        List<Feature> hitGraphics = event.getOverlay().getHitFeatures();
        GraphicsLayer graphicsLayer = (GraphicsLayer) event.getOverlay().getLayer();
        for (Feature graphic : hitGraphics) {
          int id = (int) graphic.getId();
          if (graphicsLayer.isGraphicSelected(id)) {
            // if graphic is selected in the layer, unselect it
            graphicsLayer.unselect(id);
          } else {
            // otherwise select graphic in the layer
            graphicsLayer.select(id);
          }
        }
      }
    }
  

Sample Code

/* Copyright 2014 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 com.esri.client.samples.graphics;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import com.esri.toolkit.overlays.HitTestEvent;
import com.esri.toolkit.overlays.HitTestListener;
import com.esri.toolkit.overlays.HitTestOverlay;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.MultiPoint;
import com.esri.core.geometry.Polyline;
import com.esri.core.map.Feature;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.PictureMarkerSymbol;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol;
import com.esri.core.symbol.SimpleMarkerSymbol.Style;
import com.esri.core.symbol.TextSymbol;
import com.esri.core.symbol.TextSymbol.HorizontalAlignment;
import com.esri.core.symbol.TextSymbol.VerticalAlignment;
import com.esri.map.ArcGISTiledMapServiceLayer;
import com.esri.map.GraphicsLayer;
import com.esri.map.JMap;
import com.esri.map.LayerList;

/***
 * This sample shows how to select graphics in a mixed geometry graphics layer - clicking an unselected 
 * graphic will toggle it to its selected state and vice-versa. The default selection color is cyan, 
 * and it can be changed by using the setSelectionColor method on the graphics layer. A HitTestOverlay 
 * is used to obtain the clicked graphics whenever a selection has been made.
 */
public class SimpleSelection {

  private JMap jMap;

  private GraphicsLayer graphicsLayer;

  private static final int COMPONENT_WIDTH = 220;

  // ------------------------------------------------------------------------
  // Constructor
  // ------------------------------------------------------------------------
  public SimpleSelection() {

  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------

  class GraphicSelectedListener implements HitTestListener {

    @Override
    public void featureHit(HitTestEvent event) {
      // get hit graphics
      List<Feature> hitGraphics = event.getOverlay().getHitFeatures();
      GraphicsLayer gLayer = (GraphicsLayer) event.getOverlay().getLayer();
      for (Feature graphic : hitGraphics) {
        int id = (int) graphic.getId();
        if (gLayer.isGraphicSelected(id)) {
          // if graphic is selected in the layer, unselect it
          gLayer.unselect(id);
        } else {
          // otherwise select graphic in the layer
          gLayer.select(id);
        }
      }
    }
  }

  private void addGraphics(GraphicsLayer gLayer) {
    Point equator = new Point(0, 0);
    gLayer.addGraphic(new Graphic(equator, new SimpleMarkerSymbol(Color.MAGENTA, 25, Style.CIRCLE)));

    Polyline line = new Polyline();
    line.startPath(-180, 0);
    line.lineTo(180, 0);
    gLayer.addGraphic(new Graphic(line, new SimpleLineSymbol(Color.BLACK, 2,
        com.esri.core.symbol.SimpleLineSymbol.Style.DASH)));

    Polygon polygon = new Polygon();
    polygon.startPath(-80, 25);
    polygon.lineTo(-64, 32);
    polygon.lineTo(-66, 18);
    polygon.closeAllPaths();
    gLayer.addGraphic(new Graphic(polygon, new SimpleFillSymbol(Color.RED, new SimpleLineSymbol(new Color(200, 0, 0),
        1.0f))));

    MultiPoint planes = new MultiPoint();
    PictureMarkerSymbol planeSymbol = new PictureMarkerSymbol(
        "http://static.arcgis.com/images/Symbols/Transportation/Airplane.png");
    planeSymbol.setSize(50, 50);
    Point plane1 = new Point(-40, 25);
    planes.add(plane1);
    Point plane2 = new Point(-45, 35);
    planes.add(plane2);
    Point plane3 = new Point(-30, 35);
    planes.add(plane3);
    Graphic gPlanes = new Graphic(planes, planeSymbol);
    gLayer.addGraphic(gPlanes);

    TextSymbol textSymbol = new TextSymbol(14, "Equator", Color.BLACK);
    textSymbol.setHorizontalAlignment(HorizontalAlignment.RIGHT);
    textSymbol.setVerticalAlignment(VerticalAlignment.BOTTOM);
    textSymbol.setOffsetX(-30.0f);
    gLayer.addGraphic(new Graphic(equator, textSymbol));
  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          SimpleSelection selectionApp = new SimpleSelection();

          // create the UI, including the map, for the application.
          JFrame appWindow = selectionApp.createWindow();
          appWindow.add(selectionApp.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace.
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Public methods
  // ------------------------------------------------------------------------
  public JComponent createUI() throws Exception {
    // application content
    JComponent contentPane = createContentPane();

    // selection color panel
    JPanel userPanel = createUserPanel();
    userPanel.setVisible(true);
    userPanel.setLocation(10, 10);

    // create map
    jMap = createMap();

    contentPane.add(userPanel);
    contentPane.add(jMap);

    return contentPane;
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  /**
   * Creates the map.
   * 
   * @return a map.
   */
  private JMap createMap() {

    final JMap map = new JMap();

    // add the base layer
    ArcGISTiledMapServiceLayer worldLayer = new ArcGISTiledMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer");

    map.setExtent(new Envelope(-140, -45, 50, 45));

    LayerList layers = map.getLayers();
    layers.add(worldLayer);

    // graphics layer - selection color is cyan by default
    graphicsLayer = new GraphicsLayer();
    graphicsLayer.setName("simpleGraphics");
    layers.add(graphicsLayer);
    addGraphics(graphicsLayer);

    // create the overlay and the listener
    final HitTestOverlay overlay = new HitTestOverlay(graphicsLayer);
    overlay.addHitTestListener(new GraphicSelectedListener());

    // add the overlay to the jMap
    map.addMapOverlay(overlay);

    return map;
  }

  /**
   * Creates the user panel to change the selection color.
   */
  private JPanel createUserPanel() {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setSize(COMPONENT_WIDTH, 120);
    panel.setLocation(10, 10);

    JTextArea description = new JTextArea("Click on graphics to toggle between selected and unselected "
        + "states and symbology.");
    description.setFont(new Font("Verdana", Font.PLAIN, 11));
    description.setForeground(Color.WHITE);
    description.setBackground(new Color(0, 0, 0, 0));
    description.setEditable(false);
    description.setLineWrap(true);
    description.setWrapStyleWord(true);
    description.setAlignmentX(Component.LEFT_ALIGNMENT);

    JLabel lblColor = new JLabel("Choose Selection Color:");
    lblColor.setForeground(Color.WHITE);
    lblColor.setAlignmentX(Component.LEFT_ALIGNMENT);

    final Map<String, Color> colorMap = new LinkedHashMap<>();

    colorMap.put("Cyan", Color.CYAN);
    colorMap.put("Yellow", Color.YELLOW);
    colorMap.put("Red", Color.RED);
    colorMap.put("Green", Color.GREEN);
    colorMap.put("White", Color.WHITE);

    final JComboBox<String> cbxColors = new JComboBox<>(colorMap.keySet().toArray(new String[0]));
    cbxColors.setMaximumSize(new Dimension(COMPONENT_WIDTH, 25));
    cbxColors.setAlignmentX(Component.LEFT_ALIGNMENT);
    cbxColors.addItemListener(new ItemListener() {

      @Override
      public void itemStateChanged(ItemEvent arg0) {
        if (arg0.getStateChange() == ItemEvent.SELECTED) {
          Color color = colorMap.get(cbxColors.getSelectedItem());
          graphicsLayer.setSelectionColor(color);
        }
      }
    });

    // layout all the components together into a panel
    panel.setBackground(new Color(0, 0, 0, 140));
    panel.add(description);
    panel.add(Box.createRigidArea(new Dimension(0, 5)));
    panel.add(lblColor);
    panel.add(Box.createRigidArea(new Dimension(0, 5)));
    panel.add(cbxColors);
    panel.add(Box.createRigidArea(new Dimension(0, 5)));
    panel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
    return panel;
  }

  private static JLayeredPane createContentPane() {
    JLayeredPane contentPane = new JLayeredPane();
    contentPane.setBounds(100, 100, 1000, 700);
    contentPane.setLayout(new BorderLayout(0, 0));
    contentPane.setVisible(true);
    return contentPane;
  }

  /**
   * Creates a window.
   * 
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("Simple Selection Application");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        jMap.dispose();
      }
    });
    return window;
  }
}
Feedback on this topic?