Show MapTips

One way to display information about the data in your map is by using MapTips: UI components to display feature attributes when a user hovers over a feature. The MapTip class enables you to display such components. Using this class, you can configure your MapTips to show your chosen set of attributes for features. In your application, each graphics layer (GraphicsLayer) or feature layer (ArcGISFeatureLayer or FeatureLayer) can be associated with its own MapTip object and customized independently. For each MapTip object, you can set the fields to display and customize the appearance of the MapTip. You can easily disable the MapTip for a given layer so that MapTips no longer display when the pointer hovers over a feature. Finally, for a given map control, you can set the amount of time (in milliseconds) that the pointer has to be paused over a graphic or feature before a MapTip displays.

Add MapTips to a graphics layer

A graphics layer contains graphics, and each graphic has a map of attributes (key-value pairs) associated with it. The class implementing graphics is Graphic, which implements the Feature interface, as described in Features and graphics. The graphic's attributes are passed to the Graphic constructor when the graphic is created. Typically, a graphics layer will contain graphics that all have the same set of attribute keys. For example, the graphics may have come from querying a feature layer and creating graphics whose attributes are a subset of the feature layer's fields. To display selected attributes from a graphic as a MapTip, you first create a map of display fields where the key String is equivalent to the key String in the attribute map, and the value is the formatted String as you want it to display in the MapTip. The MapTip object is then created with the display fields map and set on the graphics layer as shown in the following code snippet:

LinkedHashMap<String, String> displayFields = new LinkedHashMap<String, String>();
displayFields.put("Street", "Street: ");
displayFields.put("City", "City: ");
// ... add more display fields according to what your graphics' attributes are
MapTip mapTip = new MapTip(displayFields);
// set your MapTip on the graphics layer
graphicsLayer.setMapTip(mapTip);

You can also use the parameter-less MapTip constructor, in which case no map of display fields needs to be created and only the first attribute of the graphic will display in the graphic layer's MapTips.

Add MapTips to a feature layer

A feature layer is similar to a graphics layer but has additional functionality to support editing, selection, querying, and more. Both feature layers and graphics layers contain objects that are implementations of the Feature interface, such as GeodatabaseFeature objects and Graphic objects. Adding MapTips to a feature layer is done in the same way as for a graphics layer, with the additional constraint that any field you add to the display fields for the MapTip needs to be a valid field in the feature layer. One way to obtain the feature layer's fields is by calling the getFields() method on the initialized layer. Because of this constraint on fields being valid for a feature layer, you need to set the MapTip on the layer only after it is initialized. The following code snippet shows how to do this, placing this code in a LayerInitializeCompleteListener. The code creates and sets a MapTip for a feature layer that has fields named latitude, longitude, and datetime:

// create an ArcGISFeatureLayer
final ArcGISFeatureLayer pointsLayer = new ArcGISFeatureLayer("SERVICE_URL");
// or you could use a FeatureLayer instead
// final FeatureLayer pointsLayer = new FeatureLayer(geodatabaseFeatureTable);

// add a layer listener
pointsLayer.addLayerInitializeCompleteListener(new LayerInitializeCompleteListener() {
  @Override
  public void layerInitializeComplete(LayerInitializeCompleteEvent e) {
    if (e.getLayer().getStatus() == LayerStatus.INITIALIZED) {
      // create the map of the fields we want the MapTips to display
      LinkedHashMap<String, String> displayFields = new LinkedHashMap<String, String>();
      displayFields.put("latitude", "Latitude: ");
      displayFields.put("longitude", "Longitude: ");
      displayFields.put("datetime", "Time: ");
      // create the MapTip and set it on the feature layer
      mapTip = new MapTip(displayFields);
      pointsLayer.setMapTip(mapTip);
    }
  }
});
// add the layer to a map which will initialize the layer
map.getLayers().add(pointsLayer);

The previous code results in a MapTip, as shown in the following screen shot, when you hover over a feature (red point):

MapTip screen shot

A feature layer usually has a default field associated with it. To display only the default field in a MapTip, you can use the parameter-less MapTip constructor and avoid creating a map of display fields, as shown in the following code snippet:

// assumes 'pointsLayer' is an initialized feature layer which has a default field
MapTip mapTip = new MapTip();
pointsLayer.setMapTip(mapTip);

Customize the MapTip

Once you create a MapTip instance, you can customize its appearance by setting a custom border, a custom font for the text, and custom colors for the background and foreground (text). The following code snippet sets some custom properties on a MapTip:

// create the MapTip instance, as before
mapTip = new MapTip(displayFields);

// customize the MapTip
mapTip.setBackground(Color.WHITE);
mapTip.setForeground(Color.DARK_GRAY);
mapTip.setFont(new Font("Verdana", Font.PLAIN, 12));
mapTip.setBorder(BorderFactory.createCompoundBorder(
  new LineBorder(Color.DARK_GRAY), 
  new EmptyBorder(5, 5, 5, 5)));

// set the MapTip on a layer
pointsLayer.setMapTip(mapTip);

The MapTip instances after the above code is called will look similar to the following screen shot:

Customized MapTip UI

You can also customize the length of time that the pointer has to be paused over a graphic or feature before a MapTip displays. This is done through a method on JMap and will control the time delay for any MapTips in that map. The following code sets the MapTip delay to 100 milliseconds:

map.setMapTipDelay(100);
// MapTips will now display once the pointer has been paused over a feature for 100ms or more

Finally, you can easily show or hide MapTips for a layer by calling the setEnabled method on the relevant MapTip instance:

// disables this MapTip: will no longer show on hover
mapTip.setEnabled(false);