Map animation

Download Sample Viewer

Description

This sample shows how to customize the animation of the JMap. Turn the animation on or off by calling the method jMap.setAnimationMode(AnimationMode), and control the animation duration by calling the method jMap.setAnimationDuration(float seconds). Use the controls in the application to set these map properties. Click the navigation buttons to try out the different navigation actions with various animation settings.

Code snippet


  // turn map animation off
  map.setAnimationMode(AnimationMode.NONE);
  
  // turn map animation on
  map.setAnimationMode(AnimationMode.ANIMATE);
  
  // set the animation duration (in seconds)
  map.setAnimationDuration(0.3f);
  
  

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.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Hashtable;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.esri.core.geometry.Envelope;
import com.esri.map.JMap;
import com.esri.map.JMap.AnimationMode;
import com.esri.map.MapOptions;
import com.esri.map.MapOptions.MapType;

/**
 * This sample shows how to customize the animation of the JMap. Turn the animation 
 * on or off by calling the method <code>jMap.setAnimationMode(AnimationMode)</code>, 
 * and control the animation duration by calling the method 
 * <code>jMap.setAnimationDuration(float seconds)</code>.
 * <p>
 * Use the controls in the application to set these map properties. Click the 
 * navigation buttons to try out the different navigation actions with various 
 * animation settings.
 */
public class MapAnimationApp {

  private JComponent contentPane;
  private JMap map;
  private JSlider animationSlider;
  private int currentRotation = 0; // in degrees
  private final static int rotationAngle = 10; // in degrees
  private static final int PANEL_WIDTH = 230;
  private static final int SPACING = 10;
  public static final int COMPONENT_HEIGHT = 25;
  public static final int COMPONENT_WIDTH = PANEL_WIDTH - 2*SPACING;

  // Default constructor
  public MapAnimationApp() { }

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

    contentPane = createContentPane();

    // create map with map options
    MapOptions options = new MapOptions(MapType.TOPO, 59.329444, 18.068611, 11);
    map = new JMap(options);

    // two control panels
    JPanel animationPanel = createAnimationPanel();
    JPanel navigationPanel = createNavigationPanel(animationPanel);

    // add panels and map to layered pane
    contentPane.add(animationPanel);
    contentPane.add(navigationPanel);
    contentPane.add(map); // add map last

    return contentPane;
  }

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

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

  /**
   * Creates a JPanel to control the map animation.
   *  
   * @return a panel.
   */
  private JPanel createAnimationPanel() {

    // check box to turn animation on or off
    JCheckBox checkBox = new JCheckBox("Animate map on pan and zoom");
    checkBox.setSelected(true);
    checkBox.addItemListener(new ItemListener() {

      @Override
      public void itemStateChanged(ItemEvent e) {
        if (map.isReady()) {
          if (e.getStateChange() == ItemEvent.DESELECTED) {
            map.setAnimationMode(AnimationMode.NONE);
          } else {
            map.setAnimationMode(AnimationMode.ANIMATE);
          }
        }
      }
    });
    
    // animation slider to control the animation duration
    // default is 0.5 seconds, slider uses integer so multiplying by 100
    animationSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 50);
    animationSlider.setName("Animation");
    animationSlider.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        if (map.isReady()) {
          JSlider source = (JSlider) e.getSource();
          if (!source.getValueIsAdjusting()) {
            float seconds = source.getValue()/100.0f;
            map.setAnimationDuration(seconds);
          }
        }
      }
    });
    Hashtable<Integer, JLabel> labelTable = new Hashtable<>();
    labelTable.put(new Integer(200), new JLabel("2s"));
    labelTable.put(new Integer(150), new JLabel("1.5s"));
    labelTable.put(new Integer(100), new JLabel("1s"));
    labelTable.put(new Integer(50), new JLabel("0.5s"));
    labelTable.put(new Integer(0), new JLabel("0s"));
    animationSlider.setLabelTable(labelTable);
    animationSlider.setMajorTickSpacing(50);
    animationSlider.setMinorTickSpacing(10);
    animationSlider.setPaintTicks(true);
    animationSlider.setPaintLabels(true);
    animationSlider.setBorder(BorderFactory.createTitledBorder("Animation duration"));

    // animation panel
    final JPanel animationPanel = new JPanel();
    animationPanel.setLayout(new BorderLayout(0, 5));
    animationPanel.setLocation(SPACING, SPACING);
    animationPanel.setSize(PANEL_WIDTH, 125);
    animationPanel.setBorder(BorderFactory.createCompoundBorder(
        new LineBorder(Color.BLACK), 
        new EmptyBorder(SPACING, SPACING, SPACING, SPACING)));
    animationPanel.add(checkBox, BorderLayout.NORTH);
    animationPanel.add(animationSlider, BorderLayout.SOUTH);

    return animationPanel;
  }

  /**
   * Creates a JPanel with the user controls for navigating the map.
   *  
   * @return a panel.
   */
  private JPanel createNavigationPanel(JPanel panel) {

    JButton btnZoomUS = new FixedSizeButton("Zoom in");
    btnZoomUS.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        map.zoom(0.5);
      }
    });

    JButton btnZoomFullExtent = new FixedSizeButton("Zoom out");
    btnZoomFullExtent.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        map.zoom(2);
      }
    });

    JButton btnPanLeft = new FixedSizeButton("Pan West");
    btnPanLeft.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Envelope extent = map.getExtent();
        double panAmount = (extent.getXMax()-extent.getXMin())/4;
        extent.setXMin(extent.getXMin() - panAmount);
        extent.setXMax(extent.getXMax() - panAmount);
        map.panTo(extent);
      }
    });

    JButton btnPanRight = new FixedSizeButton("Pan East");
    btnPanRight.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Envelope extent = map.getExtent();
        double panAmount = (extent.getXMax()-extent.getXMin())/4;
        extent.setXMin(extent.getXMin() + panAmount);
        extent.setXMax(extent.getXMax() + panAmount);
        map.panTo(extent);
      }
    });

    JButton btnPanUp = new FixedSizeButton("Pan North");
    btnPanUp.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Envelope extent = map.getExtent();
        double panAmount = (extent.getYMax()-extent.getYMin())/4;
        extent.setYMin(extent.getYMin() + panAmount);
        extent.setYMax(extent.getYMax() + panAmount);
        map.panTo(extent);
      }
    });

    JButton btnPanDown = new FixedSizeButton("Pan South");
    btnPanDown.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Envelope extent = map.getExtent();
        double panAmount = (extent.getYMax()-extent.getYMin())/4;
        extent.setYMin(extent.getYMin() - panAmount);
        extent.setYMax(extent.getYMax() - panAmount);
        map.panTo(extent);
      }
    });

    JButton btnRotateLeft = new FixedSizeButton("Rotate Left");
    btnRotateLeft.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        currentRotation = (currentRotation + rotationAngle) % 360;
        map.setRotation(currentRotation);
      }
    });

    JButton btnRotateRight = new FixedSizeButton("Rotate Right");
    btnRotateRight.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        currentRotation = (currentRotation - rotationAngle);
        if (currentRotation < 0) {
          currentRotation = 360 + currentRotation;
        }
        map.setRotation(currentRotation);
      }
    });

    // navigation panel
    final JPanel controlPanel = new JPanel();
    controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
    controlPanel.setLocation(SPACING, SPACING + panel.getHeight() + SPACING);
    controlPanel.setSize(PANEL_WIDTH, 220);
    controlPanel.setBorder(BorderFactory.createCompoundBorder(
        new LineBorder(Color.BLACK), 
        new EmptyBorder(SPACING, SPACING, SPACING, SPACING)));

    controlPanel.add(btnZoomUS);
    controlPanel.add(btnZoomFullExtent);
    controlPanel.add(btnPanUp);
    controlPanel.add(btnPanDown);
    controlPanel.add(btnPanLeft);
    controlPanel.add(btnPanRight);
    controlPanel.add(btnRotateLeft);
    controlPanel.add(btnRotateRight);

    return controlPanel;
  }

  /**
   * Creates a layered content pane in order to display components on top of the map. 
   * 
   * @return a layered content pane.
   */
  private static JLayeredPane createContentPane() {
    JLayeredPane contentPane = new JLayeredPane();
    contentPane.setLayout(new BorderLayout());
    contentPane.setVisible(true);
    return contentPane;
  }

  /**
   * Creates the application window.
   * 
   * @return a window
   */
  JFrame createWindow() {
    JFrame window = new JFrame("Map Animation Application");
    window.setSize(1000, 700);
    window.setLocationRelativeTo(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        if (map != null) {
          map.dispose();
        }
      }
    });
    return window;
  }

  class FixedSizeButton extends JButton {

    private static final long serialVersionUID = 1L;
    private int width = COMPONENT_WIDTH;
    private int height = COMPONENT_HEIGHT;

    FixedSizeButton(String title) {
      super(title);
      Dimension d = new Dimension(width, height);
      setMinimumSize(d);
      setMaximumSize(d);
      setPreferredSize(d);
    }

  }
}
Feedback on this topic?