Graphics draw order

Download Sample Viewer

Description

This sample shows how to control the drawing order of graphics in a GraphicsLayer. The table displays each graphic's name, graphic id, and draw order. The controls panel allows you to move any graphic to the front or back of the drawing order. The result will be shown visually in the map, and the graphic's draw order value will be updated in the table.

Code snippet


    // bring a graphic to the front of its graphics layer
    graphicsLayer.bringToFront(graphicId);
    // send a graphic to the back of its graphics layer
    graphicsLayer.sendToBack(graphicId);
    // update the drawing order of a graphic in its graphics layer
    graphicsLayer.updateGraphic(graphicId, drawOrder);
    // perform a bulk update of drawing orders in a graphics layer
    graphicsLayer.updateGraphic(graphicIdArray, drawOrderArray);
  

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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.map.Graphic;
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.map.ArcGISTiledMapServiceLayer;
import com.esri.map.GraphicsLayer;
import com.esri.map.JMap;
import com.esri.map.LayerList;
import com.esri.map.MapEvent;
import com.esri.map.MapEventListenerAdapter;

/***
 * This sample shows how to control the drawing order of graphics in
 * a GraphicsLayer. The table displays each graphic's name, graphic ID,
 * and draw order. The controls panel allows you to move any graphic
 * to the front or back of the drawing order. The result will be
 * shown visually in the map, and the graphic's draw order value will
 * be updated in the table.
 */
public class DrawOrderApp {

  private JMap map;
  final private GraphicTableModel model = new GraphicTableModel();
  private JTable tblGraphics = new JTable(model);
  private GraphicsLayer graphicsLayer;
  private static final int NUM_GRAPHICS = 4;
  private String[] graphicNames = new String[NUM_GRAPHICS];
  private int[] graphicIds = new int[NUM_GRAPHICS];

  //------------------------------------------------------------------------
  // Constructor
  //------------------------------------------------------------------------
  public DrawOrderApp() {
  }

  //------------------------------------------------------------------------
  // Static methods
  //------------------------------------------------------------------------
  /**
   * Starting point of this application.
   * @param args arguments to this application.
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          DrawOrderApp app = new DrawOrderApp();

          // create the UI, including the map, for the application.
          JFrame appWindow = app.createWindow();
          appWindow.add(app.createUI());
          appWindow.setVisible(true);
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    });
  }

  //------------------------------------------------------------------------
  // Public methods
  //------------------------------------------------------------------------
  /**
   * Creates and displays the UI, including the map, for this application.
   * @return the UI component.
   */
  public JComponent createUI() {

    JPanel contentPanel = new JPanel();
    contentPanel.setLayout(new BorderLayout(0, 5));

    // map
    map = createMap();

    JPanel tablePanel = new JPanel();
    tablePanel.setLayout(new BorderLayout(0, 0));
    JScrollPane scrollPane = new JScrollPane(tblGraphics);
    tablePanel.add(scrollPane);
    tablePanel.setBorder(BorderFactory.createTitledBorder("Graphics:"));

    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new BorderLayout(0, 0));
    buttonPanel.add(createControlPanel());
    buttonPanel.setBorder(BorderFactory.createTitledBorder("Controls:"));


    // group the above UI items into a panel
    JPanel controlPanel = new JPanel();
    controlPanel.setLayout(new BorderLayout(0, 0));
    controlPanel.add(tablePanel, BorderLayout.CENTER);
    controlPanel.add(buttonPanel, BorderLayout.EAST);
    controlPanel.setPreferredSize(new Dimension(600, 120));
    controlPanel.setDoubleBuffered(true);

    contentPanel.add(map, BorderLayout.CENTER);
    contentPanel.add(controlPanel, BorderLayout.NORTH);

    return contentPanel;
  }

  //------------------------------------------------------------------------
  // Private methods
  //------------------------------------------------------------------------

  private JMap createMap() {

    JMap jMap = new JMap();
    // set to default extent
    jMap.setExtent(new Envelope(38.67, 14.68, 124.98, 72.25));

    // add base layer
    ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer");
    LayerList layers = jMap.getLayers();
    layers.add(tiledLayer);

    // create the graphics layer
    graphicsLayer = new GraphicsLayer();
    layers.add(graphicsLayer);

    jMap.addMapEventListener(new MapEventListenerAdapter() {
      @Override
      public void mapReady(final MapEvent arg0) {
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            addGraphics(graphicsLayer);
            initGraphicsTable();
          }
        });
      }
    });

    return jMap;
  }

  private void addGraphics(final GraphicsLayer myGraphicsLayer) {
    // red circle
    Point point1 = new Point(80, 45);
    Graphic pointGraphic1 = new Graphic(point1, new SimpleMarkerSymbol(Color.RED, 24, Style.CIRCLE));
    graphicIds[0] = myGraphicsLayer.addGraphic(pointGraphic1);
    graphicNames[0] = "Red Circle";

    // black circle
    Point point2 = new Point(70, 45);
    Graphic pointGraphic2 = new Graphic(point2, new SimpleMarkerSymbol(Color.BLACK, 18, Style.CIRCLE));
    graphicIds[1] = myGraphicsLayer.addGraphic(pointGraphic2);
    graphicNames[1] = "Black Circle";

    // blue line
    Polyline polyline = new Polyline();
    polyline.startPath(40, 45);
    polyline.lineTo(110, 45);
    SimpleLineSymbol symbol = new SimpleLineSymbol(Color.BLUE, 4);
    symbol.setStyle(SimpleLineSymbol.Style.SOLID);
    Graphic lineGraphic = new Graphic(polyline, symbol);
    graphicIds[2] = myGraphicsLayer.addGraphic(lineGraphic);
    graphicNames[2] = "Blue Line";

    // green polygon
    Polygon polygon = new Polygon();
    polygon.startPath(60, 60);
    polygon.lineTo(90, 60);
    polygon.lineTo(90, 30);
    polygon.lineTo(60, 30);
    polygon.closePathWithLine();
    SimpleLineSymbol outline = new SimpleLineSymbol(new Color(0, 200, 0), 3);
    SimpleFillSymbol symbol2 = new SimpleFillSymbol(new Color(0, 255, 0, 180), outline);
    Graphic polygonGraphic = new Graphic(polygon, symbol2);
    graphicIds[3] = myGraphicsLayer.addGraphic(polygonGraphic);
    graphicNames[3] = "Green Polygon";
  }

  private void initGraphicsTable() {
    for (int i = 0; i < graphicNames.length; i++) {
      model.setValueAt(graphicNames[i], i, 0);
      model.setValueAt(Integer.valueOf(graphicIds[i]), i, 1);
      model.setValueAt(Integer.valueOf(graphicsLayer.getGraphic(graphicIds[i]).getDrawOrder()), i, 2);
    }
  }

  private void updateGraphicsTable() {
    try {
      for (int i = 0; i < graphicNames.length; i++) {
        int id = Integer.parseInt(model.getValueAt(i, 1).toString());
        model.setValueAt(Integer.valueOf(graphicsLayer.getGraphic(id).getDrawOrder()), i, 2);
      }
    } catch (Exception ex) {
      throw new RuntimeException("Please enter integer values only.", ex);
    }
  }

  private JPanel createControlPanel() {

    JPanel buttonPanel = new JPanel();
    buttonPanel.setPreferredSize(new Dimension(450, 200));
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));

    JPanel panelFrontBack = new JPanel();
    panelFrontBack.setLayout(new BoxLayout(panelFrontBack, BoxLayout.X_AXIS));
    panelFrontBack.add(new JLabel("Bring/Send Graphic Id "));
    final JTextField txtField1 = new JTextField("  ", 10);
    txtField1.setMinimumSize(new Dimension(40, 20));
    txtField1.setMaximumSize(new Dimension(40, 20));
    panelFrontBack.add(txtField1);
    panelFrontBack.add(new JLabel(" to "));
    JButton btnMoveToFront = new JButton("front");
    btnMoveToFront.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int graphicId = Integer.parseInt(txtField1.getText().trim());
        graphicsLayer.bringToFront(graphicId);
        updateGraphicsTable();
      }
    });
    panelFrontBack.add(btnMoveToFront);
    panelFrontBack.add(new JLabel("  "));
    JButton btnMoveToBack = new JButton("back");
    btnMoveToBack.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int graphicId = Integer.parseInt(txtField1.getText().trim());
        graphicsLayer.sendToBack(graphicId);
        updateGraphicsTable();
      }
    });
    panelFrontBack.add(btnMoveToBack);
    panelFrontBack.setAlignmentX(Component.LEFT_ALIGNMENT);

    JPanel panelUpdate = new JPanel();
    panelUpdate.setLayout(new BoxLayout(panelUpdate, BoxLayout.X_AXIS));
    panelUpdate.add(new JLabel("Update Graphic Id "));
    final JTextField txtField2 = new JTextField("  ", 10);
    txtField2.setMinimumSize(new Dimension(40, 20));
    txtField2.setMaximumSize(new Dimension(40, 20));
    panelUpdate.add(txtField2);
    panelUpdate.add(new JLabel(" to draw order "));
    final JTextField txtField3 = new JTextField("  ", 10);
    txtField3.setMinimumSize(new Dimension(40, 20));
    txtField3.setMaximumSize(new Dimension(40, 20));
    panelUpdate.add(txtField3);
    panelUpdate.add(new JLabel("  "));
    JButton btnUpdate = new JButton("Update");
    btnUpdate.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int graphicId = Integer.parseInt(txtField2.getText().trim());
        int drawOrder = Integer.parseInt(txtField3.getText().trim());
        graphicsLayer.updateGraphic(graphicId, drawOrder);
        updateGraphicsTable();
      }
    });
    panelUpdate.add(btnUpdate);
    panelUpdate.setAlignmentX(Component.LEFT_ALIGNMENT);

    JPanel panelBulkUpdate = new JPanel();
    panelBulkUpdate.setLayout(new BoxLayout(panelBulkUpdate, BoxLayout.X_AXIS));
    final JButton btnBulkUpdate = new JButton("Bulk Update");
    btnBulkUpdate.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        try {
          btnBulkUpdate.grabFocus();
          int[] ids = new int[graphicNames.length];
          int[] drawOrder = new int[graphicNames.length];
          for (int i = 0; i < graphicNames.length; i++) {
            ids[i] = Integer.parseInt(model.getValueAt(i, 1).toString());
            drawOrder[i] = Integer.parseInt(model.getValueAt(i, 2).toString());
          }
          graphicsLayer.updateGraphic(ids, drawOrder);
        } catch (Exception ex) {
          throw new RuntimeException("Please enter integer values only.", ex);
        }
      }
    });
    JLabel lblBulkUpdate = new JLabel(" (edit draw order in the table)");
    panelBulkUpdate.add(btnBulkUpdate);
    panelBulkUpdate.add(lblBulkUpdate);
    panelBulkUpdate.setAlignmentX(Component.LEFT_ALIGNMENT);

    buttonPanel.add(panelBulkUpdate);
    buttonPanel.add(Box.createRigidArea(new Dimension(0, 2)));
    buttonPanel.add(panelFrontBack);
    buttonPanel.add(Box.createRigidArea(new Dimension(0, 2)));
    buttonPanel.add(panelUpdate);

    return buttonPanel;

  }

  /**
   * Creates a window.
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("Draw Order 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);
        map.dispose();
      }
    });
    return window;
  }

  class GraphicTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 1L;

    private String[] columnNames = {"Name", "ID", "Draw Order (Editable)"};

    private Object[][] data = new Object[NUM_GRAPHICS][columnNames.length];

    @Override
    public int getColumnCount() {
      return columnNames.length;
    }

    @Override
    public int getRowCount() {
      return data.length;
    }

    @Override
    public String getColumnName(int col) {
      return columnNames[col];
    }

    @Override
    public Object getValueAt(int row, int col) {
      return data[row][col];
    }

    @Override
    public boolean isCellEditable(int row, int col) {
      return col > 1;
    }

    @Override
    public void setValueAt(Object value, int row, int col) {
      data[row][col] = value;
      fireTableCellUpdated(row, col);
    }
  }
}
Feedback on this topic?