Map layer ordering

Download Sample Viewer

Description

This application demonstrates how to re-order layers within a map.

Code snippet


    private void reorderLayer(JMap jMap, int fromIndex, int toIndex) {
    jMap.getLayers().reorderLayer(fromIndex, toIndex);
    //(GroupLayer) groupLayer.reorderLayer(fromIndex, toIndex);
    }
  

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.map;

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.JOptionPane;
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.map.Graphic;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import com.esri.map.ArcGISDynamicMapServiceLayer;
import com.esri.map.ArcGISFeatureLayer;
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 order of layers in a map. The table 
 * displays each layer's name and the layer order. The reorder panel allows 
 * you to move any layer to the front or back of the layer order. The result 
 * will be shown visually in the map, and the layer's order value will
 * be updated in the table.
 */
public class LayerOrderApp {

  private JMap map;
  final private LayerTableModel model = new LayerTableModel();
  private JTable tablLayers = new JTable(model);

  private ArcGISTiledMapServiceLayer tiledLayer;
  private GraphicsLayer graphicsLayer;
  private ArcGISDynamicMapServiceLayer dynamicLayer;
  private ArcGISFeatureLayer featureLayer;
  private static final int NUM_LAYERS = 4;

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

  //------------------------------------------------------------------------
  // Core functionality
  //------------------------------------------------------------------------
  private void reorderLayer(JMap jMap, int fromIndex, int toIndex) {
    jMap.getLayers().reorderLayer(fromIndex, toIndex);
  }

  //------------------------------------------------------------------------
  // 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
          LayerOrderApp app = new LayerOrderApp();

          // 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(tablLayers);
    tablePanel.add(scrollPane);
    tablePanel.setBorder(BorderFactory.createTitledBorder("Layers:"));

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

    // 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();
    jMap.setExtent(new Envelope(new Point(-122.41, 37.77), 0.125, 0.125));

    LayerList layers = jMap.getLayers();

    // tiled layer
    tiledLayer = new ArcGISTiledMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer");
    tiledLayer.setName("Tiled Layer");
    layers.add(tiledLayer);

    // dynamic layer
    dynamicLayer = new ArcGISDynamicMapServiceLayer(
        "http://services.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Unemployment_Rate/MapServer");
    dynamicLayer.setName("Dynamic Layer (Unemployment Rate)");
    layers.add(dynamicLayer);

    // feature layer
    featureLayer = new ArcGISFeatureLayer(
        "http://sampleserver6.arcgisonline.com/arcgis/rest/services/SF311/FeatureServer/0");
    featureLayer.setName("Feature Layer (San Francisco incidents)");
    layers.add(featureLayer);

    // graphics layer
    graphicsLayer = new GraphicsLayer();
    graphicsLayer.setName("Graphics Layer (Black rectangle)");
    layers.add(graphicsLayer);

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

    return jMap;
  }

  private void addGraphics(final GraphicsLayer gLayer) {
    // black polygon
    SimpleLineSymbol outline = new SimpleLineSymbol(Color.BLACK, 3);
    SimpleFillSymbol symbol2 = new SimpleFillSymbol(new Color(0, 0, 0, 180), outline);
    Envelope polygon = new Envelope(new Point(-122.41, 37.77), 0.025, 0.025);
    Graphic polygonGraphic = new Graphic(polygon, symbol2);
    gLayer.addGraphic(polygonGraphic);
  }

  private void updateLayerTable() {
    try {
      LayerList layers = map.getLayers();
      for (int i = 0; i < layers.size(); i++) {
        model.setValueAt(layers.get(i).getName(), i, 0);
        model.setValueAt(new Integer(i), i, 1);
      }
    } 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 Layer 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.setFocusPainted(false);
    btnMoveToFront.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int layerId = parseInt(txtField1.getText().trim());
        reorderLayer(map, layerId, map.getLayers().size() - 1);
        updateLayerTable();
      }
    });
    panelFrontBack.add(btnMoveToFront);
    panelFrontBack.add(new JLabel("  "));
    JButton btnMoveToBack = new JButton("back");
    btnMoveToBack.setFocusPainted(false);
    btnMoveToBack.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int layerId = parseInt(txtField1.getText().trim());
        reorderLayer(map, layerId, 0);
        updateLayerTable();
      }
    });
    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 Layer order from "));
    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 "));
    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.setFocusPainted(false);
    btnUpdate.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        int layerID = parseInt(txtField2.getText().trim());
        int toIndex = parseInt(txtField3.getText().trim());
        reorderLayer(map, layerID, toIndex);
        updateLayerTable();
      }
    });
    panelUpdate.add(btnUpdate);
    panelUpdate.setAlignmentX(Component.LEFT_ALIGNMENT);

    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("Layer 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;
  }

  private int parseInt(String txt) {
    int result = 0;
    try {
      result = Integer.parseInt(txt);
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(map, "Please enter integer values only.", "",
          JOptionPane.WARNING_MESSAGE);
    }
    return result;
  }

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

    private String[] columnNames = {"Name", "Layer Order"};

    private Object[][] data = new Object[NUM_LAYERS][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 false;
    }

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