Add a map to your app

The primary way to display geographic information in your apps is through a map. ArcGIS Runtime SDK for Java contains a JMap component that lets you view map layers from different sources such as ArcGIS for Server services, Bing Maps, Open Street Map, and so on. You can also use JMap to display preconfigured web maps from ArcGIS Online or your Portal for ArcGIS, as described in Build a web mapping app.

The following steps guide you through adding a map to your app, explaining key concepts along the way. Your map will display an online tiled layer from an ArcGIS for Server map service, as well as a graphics layer displaying a marker graphic. These steps assume basic knowledge about the Java Swing framework, used by ArcGIS Runtime SDK for Java.

Alternatively, create a new map application in your supported Eclipse IDE using the ArcGIS Runtime SDK for Java map application template, as described in Create a simple map application.

Create a map control

  1. Add the ArcGIS Runtime dependent jar files to the build path of your Java project. These files are located in the <installation directory>/sdk/jars folder laid down at installation.
  2. Import the Swing map control called JMap found in the com.esri.map package.
    import com.esri.map.JMap;
  3. Add the JMap to the container of your choice. For example, add it to the content pane of a JFrame application window after setting a BorderLayout on the content pane. A BorderLayout's CENTER area is a good choice for displaying the map control, as it can stretch both horizontally and vertically to fill any space not used up by other components.
    JFrame window = new JFrame();
    window.setSize(800, 600);
    window.setLocationRelativeTo(null); // center on screen
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout());
    window.setVisible(true);
    
    JMap map = new JMap();
    window.getContentPane().add(map, BorderLayout.CENTER);
    An alternative is to create your own content pane, such as a JLayeredPane or the more generic JPanel, assign it a layout, then add the JMap to this content pane.
  4. Call the dispose method on the JMap when you're done with the map control. For example, add a window listener to your application window to dispose the map when the application window is closed. This step requires you to either make your JMap instance final (shown below) or make it an application field instead.
    ...
    final JMap map = new JMap();
    window.getContentPane().add(map, BorderLayout.CENTER);
    
    // dispose map just before application window is closed.
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        map.dispose();
      }
    });

Add layers with code

Now that you have a map control in your Swing app, you need to add layers to it to display geographic data. A map is composed of a series of layers, stacked on top of each other. Typically a tiled layer is added first as a basemap, then operational layers such as feature layers and dynamic layers are added next, to be displayed on top of the basemap. Finally, graphics layers are added last to display client-side graphics such as query results, geocoding results, moving objects being tracked in real-time, and so on. See Maps and layers for more information. All of the layers in the API inherit from the class Layer, and all are added to the map using the same coding pattern.

Complete the following steps to add a tiled map service layer and a graphics layer to your map. The tiled layer will be your map's basemap, and you will display graphics on top of this basemap in the graphics layer.

  1. Import the tiled map service class ArcGISTiledMapServiceLayer found in the com.esri.map package.
    import com.esri.map.ArcGISTiledMapServiceLayer;
  2. Create an ArcGISTiledMapServiceLayer instance by passing in the URL to an ArcGIS map service endpoint. The following code snippet shows the URL to the ArcGIS World Topographic Map map service endpoint:
    ...
    ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
      "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
    Dive-in:

    Open the URL to the World Topographic Map map service endpoint in a browser to see information about the service, including its description, spatial reference, tile info, and full extent.

  3. Add the tiled map service layer to your map's layer list. This first layer will set the spatial reference of your map; in this case, to the map service's spatial reference, which is the spatial reference with the well-known ID (wkid) of 102100.
    ...
    ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
     "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
    
    // add tiled layer to map
    map.getLayers().add(tiledLayer);
    Your app now contains a map control that displays a tiled layer as a basemap. When you run the app, the tiled layer will default to its full extent, which, in this case, is the world extent.
  4. Set the map extent to focus on your area of interest. The following code snippet sets the extent to an Envelope geometry around Edinburgh, Scotland. Make sure to import the com.esri.core.geometry.Envelope class.
    import com.esri.core.geometry.Envelope; 
    ...
    map.getLayers().add(tiledLayer);
    
    // set the map extent to Edinburgh, Scotland
    map.setExtent(new Envelope(-371147, 7536055, -341260, 7557266));
    The Envelope object in this case is constructed using the maximum and minimum x and y coordinates of the rectangular area to display in the map's units (metres in this case). You can also construct an Envelope using a Point, a width, and a height.
  5. Import the graphics layer class GraphicsLayer found in the com.esri.map package.
    import com.esri.map.GraphicsLayer;
  6. Create a graphics layer and, optionally, give it a name.
    ...
    GraphicsLayer graphicsLayer = new GraphicsLayer();
    graphicsLayer.setName("Marker graphics");
  7. Add the graphics layer to your map's layer list. The graphics layer does not yet contain any graphics, so your map at this stage only displays the basemap you added earlier. Make sure to add the graphics layer last (after you add the basemap) so that it will be the top-most layer in the map's stack of layers.
    ...
    GraphicsLayer graphicsLayer = new GraphicsLayer();
    graphicsLayer.setName("Marker graphics");
    
    // add graphics layer to map
    map.getLayers().add(graphicsLayer);

Listen to map events

Your map now has a tiled layer basemap and an empty graphics layer on top of the basemap. You will now add a graphic to the graphics layer. You must do this when the map is "ready" to work with, meaning it has a spatial reference set. Complete the following steps to listen for the mapReady event, and add a graphic when this event fires.

  1. Add a MapEventListener to your map using the addMapEventListener method. The simplest way to do this in your IDE is to type map.addMapEventListener(new , then press Ctlr-Space to see code completion options. The first option should be MapEventListener. Press Enter to select this option, then add a semicolon after the final parenthesis. The following anonymous class with method stubs appears:
    map.addMapEventListener(new MapEventListener() {
    
      @Override
      public void mapReady(MapEvent event) {
        // TODO Auto-generated method stub
      }
    
      @Override
      public void mapExtentChanged(MapEvent event) {
        // TODO Auto-generated method stub
      }
    
      @Override
      public void mapDispose(MapEvent event) {
        // TODO Auto-generated method stub
      }
    }); // semi-colon to add
    Make sure to import the relevant classes: com.esri.map.MapEventListener and com.esri.map.MapEvent. In Eclipse, import any missing classes by pressing Ctrl-Shift-O.
  2. The MapEventListener class has three map events that you can listen for. You are only interested in listening to the mapReady event, so use the MapEventListenerAdapter instead, which allows you to only listen to a subset of the events. Add Adapter after MapEventListener, and remove the method stubs for mapExtentChanged and mapDispose.
    map.addMapEventListener(new MapEventListenerAdapter() {
    
      @Override
      public void mapReady(MapEvent event) {
        // TODO Auto-generated method stub
      }
    });
  3. Print the map spatial reference's well-known ID (wkid) when the mapReady event fires.
    map.addMapEventListener(new MapEventListenerAdapter() {
    
      @Override
      public void mapReady(MapEvent event) {
        // get the spatial reference from the map that fired this event
        SpatialReference mapSR = event.getMap().getSpatialReference();
        // print the spatial reference's ID
        System.out.println("The map spatial reference is wkid=" + mapSR.getID());
      }
    });

When you run your app, you now see the map centered on your chosen extent, as before, and additionally you see the following statement in your console window once the map ready event fires: "The map spatial reference is wkid=102100".

Add a marker graphic

Complete the following steps to add a marker graphic to the graphics layer when the mapReady event has fired.

  1. In the mapReady method implementation you started previously, create a Point. For this example, use the latitude longitude coordinates of Edinburgh Castle for your point: 55.9486° N, 3.2008° W. You can find a point suitable for your area of interest if you chose one other than Edinburgh. Create a point in the map's spatial reference by projecting these latitude longitude coordinates using GeometryEngine's project method.
    map.addMapEventListener(new MapEventListenerAdapter() {
    
      @Override
      public void mapReady(MapEvent event) {
        SpatialReference mapSR = event.getMap().getSpatialReference();
        System.out.println("The map spatial reference is wkid=" + mapSR.getID());
    
        // create a Point in the map's spatial reference from lon, lat coordinates
        Point point = GeometryEngine.project(-3.2008, 55.9486, mapSR);
      }
    });
    Caution:

    Make sure to import com.esri.core.geometry.Point, and not java.awt.Point.

  2. Create a symbol for your point, such as a PictureMarkerSymbol from an image URL.
    ...
        Point point = GeometryEngine.project(-3.2008, 55.9486, mapSR);
    
        // create a PictureMarkerSymbol from a URL
        PictureMarkerSymbol symbol = new PictureMarkerSymbol(
          "http://static.arcgis.com/images/Symbols/Basic/RedShinyPin.png");
  3. Create a graphic using the Point geometry and symbol you created.
    ...
        Point point = GeometryEngine.project(-3.2008, 55.9486, mapSR);
        PictureMarkerSymbol symbol = new PictureMarkerSymbol(
          "http://static.arcgis.com/images/Symbols/Basic/RedShinyPin.png");
    
        // create a graphic using the point and symbol
        Graphic pointGraphic = new Graphic(point, symbol);
  4. Add your graphic to the graphics layer you created earlier.
    ...
        Graphic pointGraphic = new Graphic(point, symbol);
    
        // add the graphic to your graphics layer
        graphicsLayer.addGraphic(pointGraphic);
    This line of code will require you to make your graphicsLayer instance final or make it an application field instead, as you had to do for your map instance.

When you run your app, you now see the map centered on your chosen extent, and when the mapReady event fires, a graphic appears at the specified point coordinates. If you chose the suggested Edinburgh extent and Edinburgh Castle point coordinates, your app should look like the following screen shot:

App screen shot for tutorial

Learn more about working with the map, map events, and graphics by studying samples in the ArcGIS Runtime SDK for Java sample viewer application installed with the SDK. The full sample code is available for each sample app for you to use and modify for your own applications.