Style a feature layer

Learn how to apply renderers and label definitions to a feature layer based on attribute values.

style a feature layer

Applications can display feature layer data with different styles to enhance the visualization. The type of Renderer you choose depends on your application. A SimpleRenderer applies the same symbol to all features, a UniqueValueRenderer applies a different symbol to each unique attribute value, and a ClassBreaksRenderer applies a symbol to a range of numeric values. Renderers are responsible for accessing the data and applying the appropriate symbol to each feature when the layer draws. You can also use a LabelDefinition to show attribute information for features. Visit the Styles and data visualization documentation to learn more about styling layers.

You can also author, style and save web maps, web scenes, and layers as portal items and then add them to the map in your application. Visit the following tutorials to learn more about adding portal items.

In this tutorial, you will apply different renderers to enhance the visualization of three feature layers with data for the Santa Monica Mountains: Trailheads with a single symbol, Trails based on elevation change and bike use, and Parks and Open Spaces based on the type of park.

Prerequisites

The following are required for this tutorial:

  1. An ArcGIS account to access your API keys. If you don't have an account, sign up for free.
  2. Confirm that your system meets the minimum system requirements.
  3. An IDE for Java.

Steps

Open a Java project with Gradle

  1. To start this tutorial, complete the Display a map tutorial, or download and unzip the Display a map solution into a new folder.

  2. Open the build.gradle file as a project in IntelliJ IDEA.

  3. If you downloaded the solution project, set your API key.

    An API Key enables access to services, web maps, and web scenes hosted in ArcGIS Online.

    1. Go to your developer dashboard to get your API key. For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.

    2. In the IntelliJ IDEA > Project tool window, open src/main/java/com.example.app and click App.

    3. In the start() method, set the API key property on the ArcGISRuntimeEnvironment with your API key. Replace YOUR_API_KEY with your actual API Key. Be sure to surround your API Key with quotes, because the parameter passed to setApiKey is a string.

      App.java
      Use dark colors for code blocks
                                                                                   
      Change lineChange lineChange lineChange line
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      
      //   Copyright 2020 Esri
      //   Licensed under the Apache License, Version 2.0 (the "License");
      //   you may not use this file except in compliance with the License.
      //   You may obtain a copy of the License at
      //
      //   http://www.apache.org/licenses/LICENSE-2.0
      //
      //   Unless required by applicable law or agreed to in writing, software
      //   distributed under the License is distributed on an "AS IS" BASIS,
      //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      //   See the License for the specific language governing permissions and
      //   limitations under the License.
      
      package com.example.app;
      
      import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
      import com.esri.arcgisruntime.mapping.ArcGISMap;
      import com.esri.arcgisruntime.mapping.BasemapStyle;
      import com.esri.arcgisruntime.mapping.Viewpoint;
      import com.esri.arcgisruntime.mapping.view.MapView;
      
      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;
      
      public class App extends Application {
      
        private MapView mapView;
      
        public static void main(String[] args) {
          Application.launch(args);
        }
      
        @Override
        public void start(Stage stage) {
          // set the title and size of the stage and show it
          stage.setTitle("Display a map tutorial");
          stage.setWidth(800);
          stage.setHeight(700);
          stage.show();
      
          // create a JavaFX scene with a stack pane as the root node, and add it to the scene
          StackPane stackPane = new StackPane();
          Scene scene = new Scene(stackPane);
          stage.setScene(scene);
      
          // Note: it is not best practice to store API keys in source code.
          // The API key is referenced here for the convenience of this tutorial.
          String yourApiKey = "YOUR_API_KEY";
          ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
      
          // create a map view to display the map and add it to the stack pane
          mapView = new MapView();
          stackPane.getChildren().add(mapView);
      
          ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
      
          // set the map on the map view
          mapView.setMap(map);
      
          mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 144447.638572));
      
        }
      
        /**
         * Stops and releases all resources used in application.
         */
        @Override
        public void stop() {
          if (mapView != null) {
            mapView.dispose();
          }
        }
      
      }
      

Preconfigure app

Modify the files from the Display a map tutorial so they can be used in this tutorial: you will change the app title, modify the viewpoint, and move the declaration of the map variable.

  1. In the start() lifecycle method, change the title that will appear on the application window to Style a feature layer.

    App.java
    Use dark colors for code blocks
    69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 68 67 66 65 64 63 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 63 64 65 66 67 68 69 70 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 70 69 68 67 66 65 64 63 62 61 61 61 61 61 61 61 61 61 61 61 61 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -123
    Change lineChange line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0";
      private final String trailheadImage = "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png";
    
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
    
        // set the title and size of the stage and show it
        stage.setTitle("Style a feature layer");
    
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEy";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 72000.0));
    
        addOpenSpaceLayer();
    
        addTrailsLayer();
    
        addBikeOnlyTrailsLayer();
    
        addNoBikesTrailsLayer();
    
        addTrailHeadsLayer();
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
      private FeatureLayer addFeatureLayer(String featureServiceUri){
        // Create a service feature table from a Uri.
        ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(featureServiceUri);
        // Create a feature layer from the service feature table.
        FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
        // Add the feature layer to the map's list of operational layers.
        map.getOperationalLayers().add(featureLayer);
        // return the feature layer
        return featureLayer;
      }
    
      private void addOpenSpaceLayer() {
        // Create a parks and open spaces feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(parksAndOpenSpaces);
    
        // Create fill symbols.
        SimpleFillSymbol purpleFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, PURPLE, null);
        SimpleFillSymbol greenFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, GREEN, null);
        SimpleFillSymbol blueFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, BLUE, null);
        SimpleFillSymbol redFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, RED, null);
    
        // Create a unique value for natural areas, regional open spaces, local parks, and regional recreation parks.
        List<Object> naturalAreasValue = new ArrayList<>();
        naturalAreasValue.add("Natural Areas");
        UniqueValue naturalAreas =
            new UniqueValue("Natural Areas", "Natural Areas", purpleFillSymbol, naturalAreasValue);
    
        List<Object> regionalOpenSpaceValue = new ArrayList<>();
        naturalAreasValue.add("Regional Open Space");
        UniqueValue regionalOpenSpace =
            new UniqueValue("Regional Open Space", "Regional Open Space", greenFillSymbol, regionalOpenSpaceValue);
    
        List<Object> localParkValue = new ArrayList<>();
        localParkValue.add("Local Park");
        UniqueValue localPark =
            new UniqueValue("Local Park", "Local Park", blueFillSymbol, localParkValue);
    
        List<Object> regionalRecreationParkValue = new ArrayList<>();
        regionalRecreationParkValue.add("Regional Recreation Park");
        UniqueValue regionalRecreationPark =
            new UniqueValue("Regional Recreation Park", "Regional Recreation Park", redFillSymbol, regionalRecreationParkValue);
    
        List<UniqueValue> uniqueValuesList = new ArrayList<>();
        uniqueValuesList.add(naturalAreas);
        uniqueValuesList.add(regionalOpenSpace);
        uniqueValuesList.add(localPark);
        uniqueValuesList.add(regionalRecreationPark);
    
        // Create a unique value renderer and set it on the parks and open spaces feature layer.
        // fieldNames is a List, but in this tutorial there is only one item in the list
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("TYPE");
        UniqueValueRenderer openSpacesUniqueValueRenderer =
            new UniqueValueRenderer(fieldNames, uniqueValuesList, "Open Spaces", null);
        featureLayer.setRenderer(openSpacesUniqueValueRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.2f);
      }
    
      private void addTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Create simple line symbols.
        SimpleLineSymbol firstClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 3.0f);
        SimpleLineSymbol secondClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 4.0f);
        SimpleLineSymbol thirdClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 5.0f);
        SimpleLineSymbol fourthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 6.0f);
        SimpleLineSymbol fifthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 7.0f);
    
        // Create five class breaks.
        ClassBreak firstClassBreak =
            new ClassBreak("Under 500", "0 - 500", 0.0, 500.0, firstClassSymbol);
        ClassBreaksRenderer.ClassBreak secondClassBreak =
            new  ClassBreak("501 to 1000", "501 - 1000", 501.0, 1000.0, secondClassSymbol);
        ClassBreak thirdClassBreak =
            new  ClassBreak("1001 to 1500", "1001 - 1500", 1001.0, 1500.0, thirdClassSymbol);
        ClassBreak fourthClassBreak =
            new  ClassBreak("1501 to 2000", "1501 - 2000", 1501.0, 2000.0, fourthClassSymbol);
        ClassBreak fifthClassBreak =
            new ClassBreak("2001 to 2300", "2001 - 2300", 2001.0, 2300.0, fifthClassSymbol);
    
        List<ClassBreak> elevationBreaks = new ArrayList<>();
        elevationBreaks.add(firstClassBreak);
        elevationBreaks.add(secondClassBreak);
        elevationBreaks.add(thirdClassBreak);
        elevationBreaks.add(fourthClassBreak);
        elevationBreaks.add(fifthClassBreak);
    
        // Create a class breaks renderer and set it on the feature layer.
        ClassBreaksRenderer elevationClassBreaksRenderer =
            new ClassBreaksRenderer("ELEV_GAIN", elevationBreaks);
        featureLayer.setRenderer(elevationClassBreaksRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.75f);
    
      }
    
      private void addBikeOnlyTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'Yes'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol bikeTrailSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, BLUE, 2.0f);
        SimpleRenderer bikeTrailRenderer = new SimpleRenderer(bikeTrailSymbol);
        featureLayer.setRenderer(bikeTrailRenderer);
    
      }
    
      private void addNoBikesTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that don't permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'No'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol noBikeTrailSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, RED, 2.0f);
        SimpleRenderer noBikeTrailRenderer =
            new SimpleRenderer(noBikeTrailSymbol);
        featureLayer.setRenderer(noBikeTrailRenderer);
      }
    
      private LabelDefinition makeLabelDefinition(String labelAttribute){
        // Create a new text symbol.
        TextSymbol labelTextSymbol  = new TextSymbol();
        labelTextSymbol.setColor(WHITE);
        labelTextSymbol.setSize(12.0f);
        labelTextSymbol.setHaloColor(RED);
        labelTextSymbol.setHaloWidth(1.0f);
        labelTextSymbol.setFontFamily("Arial");
        labelTextSymbol.setFontStyle(TextSymbol.FontStyle.ITALIC);
        labelTextSymbol.setFontWeight(TextSymbol.FontWeight.NORMAL);
    
        // Create a new Arcade label expression based on the field name.
        ArcadeLabelExpression labelExpression =
            new ArcadeLabelExpression("$feature." + labelAttribute);
    
        // Create and return the label definition.
        return new LabelDefinition(labelExpression, labelTextSymbol);
    
      }
    
      private void addTrailHeadsLayer() {
    
        // Create a trailheads feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trailheads);
    
        // Create a new picture marker symbol that uses the trailhead image.
        PictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbol(trailheadImage);
        pictureMarkerSymbol.setHeight(18.0f);
        pictureMarkerSymbol.setWidth(18.0f);
    
    
        // Create a new simple renderer based on the picture marker symbol.
        SimpleRenderer simpleRenderer = new SimpleRenderer(pictureMarkerSymbol);
    
        // Set the feature layer's renderer, and enable labels.
        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setLabelsEnabled(true);
    
        // Create the label definition.
        LabelDefinition trailHeadsDefinition = makeLabelDefinition("TRL_NAME");
    
        // Add the label definition to the layer's list of label definitions.
        featureLayer.getLabelDefinitions().add(trailHeadsDefinition);
    
      }
    
    }
    
  2. Modify the Viewpoint constructor call so it passes a scale parameter of 72.000.0, which is more appropriate to this tutorial.

    App.java
    Use dark colors for code blocks
                                                                                                                                                                                                                                                                                                                       
    Change line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0";
      private final String trailheadImage = "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png";
    
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
    
        // set the title and size of the stage and show it
        stage.setTitle("Style a feature layer");
    
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEy";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 72000.0));
    
        addOpenSpaceLayer();
    
        addTrailsLayer();
    
        addBikeOnlyTrailsLayer();
    
        addNoBikesTrailsLayer();
    
        addTrailHeadsLayer();
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
      private FeatureLayer addFeatureLayer(String featureServiceUri){
        // Create a service feature table from a Uri.
        ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(featureServiceUri);
        // Create a feature layer from the service feature table.
        FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
        // Add the feature layer to the map's list of operational layers.
        map.getOperationalLayers().add(featureLayer);
        // return the feature layer
        return featureLayer;
      }
    
      private void addOpenSpaceLayer() {
        // Create a parks and open spaces feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(parksAndOpenSpaces);
    
        // Create fill symbols.
        SimpleFillSymbol purpleFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, PURPLE, null);
        SimpleFillSymbol greenFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, GREEN, null);
        SimpleFillSymbol blueFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, BLUE, null);
        SimpleFillSymbol redFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, RED, null);
    
        // Create a unique value for natural areas, regional open spaces, local parks, and regional recreation parks.
        List<Object> naturalAreasValue = new ArrayList<>();
        naturalAreasValue.add("Natural Areas");
        UniqueValue naturalAreas =
            new UniqueValue("Natural Areas", "Natural Areas", purpleFillSymbol, naturalAreasValue);
    
        List<Object> regionalOpenSpaceValue = new ArrayList<>();
        naturalAreasValue.add("Regional Open Space");
        UniqueValue regionalOpenSpace =
            new UniqueValue("Regional Open Space", "Regional Open Space", greenFillSymbol, regionalOpenSpaceValue);
    
        List<Object> localParkValue = new ArrayList<>();
        localParkValue.add("Local Park");
        UniqueValue localPark =
            new UniqueValue("Local Park", "Local Park", blueFillSymbol, localParkValue);
    
        List<Object> regionalRecreationParkValue = new ArrayList<>();
        regionalRecreationParkValue.add("Regional Recreation Park");
        UniqueValue regionalRecreationPark =
            new UniqueValue("Regional Recreation Park", "Regional Recreation Park", redFillSymbol, regionalRecreationParkValue);
    
        List<UniqueValue> uniqueValuesList = new ArrayList<>();
        uniqueValuesList.add(naturalAreas);
        uniqueValuesList.add(regionalOpenSpace);
        uniqueValuesList.add(localPark);
        uniqueValuesList.add(regionalRecreationPark);
    
        // Create a unique value renderer and set it on the parks and open spaces feature layer.
        // fieldNames is a List, but in this tutorial there is only one item in the list
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("TYPE");
        UniqueValueRenderer openSpacesUniqueValueRenderer =
            new UniqueValueRenderer(fieldNames, uniqueValuesList, "Open Spaces", null);
        featureLayer.setRenderer(openSpacesUniqueValueRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.2f);
      }
    
      private void addTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Create simple line symbols.
        SimpleLineSymbol firstClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 3.0f);
        SimpleLineSymbol secondClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 4.0f);
        SimpleLineSymbol thirdClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 5.0f);
        SimpleLineSymbol fourthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 6.0f);
        SimpleLineSymbol fifthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 7.0f);
    
        // Create five class breaks.
        ClassBreak firstClassBreak =
            new ClassBreak("Under 500", "0 - 500", 0.0, 500.0, firstClassSymbol);
        ClassBreaksRenderer.ClassBreak secondClassBreak =
            new  ClassBreak("501 to 1000", "501 - 1000", 501.0, 1000.0, secondClassSymbol);
        ClassBreak thirdClassBreak =
            new  ClassBreak("1001 to 1500", "1001 - 1500", 1001.0, 1500.0, thirdClassSymbol);
        ClassBreak fourthClassBreak =
            new  ClassBreak("1501 to 2000", "1501 - 2000", 1501.0, 2000.0, fourthClassSymbol);
        ClassBreak fifthClassBreak =
            new ClassBreak("2001 to 2300", "2001 - 2300", 2001.0, 2300.0, fifthClassSymbol);
    
        List<ClassBreak> elevationBreaks = new ArrayList<>();
        elevationBreaks.add(firstClassBreak);
        elevationBreaks.add(secondClassBreak);
        elevationBreaks.add(thirdClassBreak);
        elevationBreaks.add(fourthClassBreak);
        elevationBreaks.add(fifthClassBreak);
    
        // Create a class breaks renderer and set it on the feature layer.
        ClassBreaksRenderer elevationClassBreaksRenderer =
            new ClassBreaksRenderer("ELEV_GAIN", elevationBreaks);
        featureLayer.setRenderer(elevationClassBreaksRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.75f);
    
      }
    
      private void addBikeOnlyTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'Yes'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol bikeTrailSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, BLUE, 2.0f);
        SimpleRenderer bikeTrailRenderer = new SimpleRenderer(bikeTrailSymbol);
        featureLayer.setRenderer(bikeTrailRenderer);
    
      }
    
      private void addNoBikesTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that don't permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'No'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol noBikeTrailSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, RED, 2.0f);
        SimpleRenderer noBikeTrailRenderer =
            new SimpleRenderer(noBikeTrailSymbol);
        featureLayer.setRenderer(noBikeTrailRenderer);
      }
    
      private LabelDefinition makeLabelDefinition(String labelAttribute){
        // Create a new text symbol.
        TextSymbol labelTextSymbol  = new TextSymbol();
        labelTextSymbol.setColor(WHITE);
        labelTextSymbol.setSize(12.0f);
        labelTextSymbol.setHaloColor(RED);
        labelTextSymbol.setHaloWidth(1.0f);
        labelTextSymbol.setFontFamily("Arial");
        labelTextSymbol.setFontStyle(TextSymbol.FontStyle.ITALIC);
        labelTextSymbol.setFontWeight(TextSymbol.FontWeight.NORMAL);
    
        // Create a new Arcade label expression based on the field name.
        ArcadeLabelExpression labelExpression =
            new ArcadeLabelExpression("$feature." + labelAttribute);
    
        // Create and return the label definition.
        return new LabelDefinition(labelExpression, labelTextSymbol);
    
      }
    
      private void addTrailHeadsLayer() {
    
        // Create a trailheads feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trailheads);
    
        // Create a new picture marker symbol that uses the trailhead image.
        PictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbol(trailheadImage);
        pictureMarkerSymbol.setHeight(18.0f);
        pictureMarkerSymbol.setWidth(18.0f);
    
    
        // Create a new simple renderer based on the picture marker symbol.
        SimpleRenderer simpleRenderer = new SimpleRenderer(pictureMarkerSymbol);
    
        // Set the feature layer's renderer, and enable labels.
        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setLabelsEnabled(true);
    
        // Create the label definition.
        LabelDefinition trailHeadsDefinition = makeLabelDefinition("TRL_NAME");
    
        // Add the label definition to the layer's list of label definitions.
        featureLayer.getLabelDefinitions().add(trailHeadsDefinition);
    
      }
    
    }
    
  3. Move the declaration of the map variable to the top level of the App class. Since map will be accessed from a new method later, it must be a field of the class, rather than a local variable in start().

    App.java
    Use dark colors for code blocks
    57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 58 59 60 61 62 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
    Remove line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    
    //   Copyright 2020 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.view.MapView;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class App extends Application {
    
      private MapView mapView;
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
        // set the title and size of the stage and show it
        stage.setTitle("Display a map tutorial");
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEY";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 144447.638572));
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
    }
    
    App.java
    Use dark colors for code blocks
    42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 43 44 45 46 47 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 49 50 51 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 52 51 50 49 48 47 46 45 44 43 42 42 42 42 42 42 42 42 42 42 42 42 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -142
    Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0";
      private final String trailheadImage = "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png";
    
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
    
        // set the title and size of the stage and show it
        stage.setTitle("Style a feature layer");
    
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEy";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 72000.0));
    
        addOpenSpaceLayer();
    
        addTrailsLayer();
    
        addBikeOnlyTrailsLayer();
    
        addNoBikesTrailsLayer();
    
        addTrailHeadsLayer();
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
      private FeatureLayer addFeatureLayer(String featureServiceUri){
        // Create a service feature table from a Uri.
        ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(featureServiceUri);
        // Create a feature layer from the service feature table.
        FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
        // Add the feature layer to the map's list of operational layers.
        map.getOperationalLayers().add(featureLayer);
        // return the feature layer
        return featureLayer;
      }
    
      private void addOpenSpaceLayer() {
        // Create a parks and open spaces feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(parksAndOpenSpaces);
    
        // Create fill symbols.
        SimpleFillSymbol purpleFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, PURPLE, null);
        SimpleFillSymbol greenFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, GREEN, null);
        SimpleFillSymbol blueFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, BLUE, null);
        SimpleFillSymbol redFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, RED, null);
    
        // Create a unique value for natural areas, regional open spaces, local parks, and regional recreation parks.
        List<Object> naturalAreasValue = new ArrayList<>();
        naturalAreasValue.add("Natural Areas");
        UniqueValue naturalAreas =
            new UniqueValue("Natural Areas", "Natural Areas", purpleFillSymbol, naturalAreasValue);
    
        List<Object> regionalOpenSpaceValue = new ArrayList<>();
        naturalAreasValue.add("Regional Open Space");
        UniqueValue regionalOpenSpace =
            new UniqueValue("Regional Open Space", "Regional Open Space", greenFillSymbol, regionalOpenSpaceValue);
    
        List<Object> localParkValue = new ArrayList<>();
        localParkValue.add("Local Park");
        UniqueValue localPark =
            new UniqueValue("Local Park", "Local Park", blueFillSymbol, localParkValue);
    
        List<Object> regionalRecreationParkValue = new ArrayList<>();
        regionalRecreationParkValue.add("Regional Recreation Park");
        UniqueValue regionalRecreationPark =
            new UniqueValue("Regional Recreation Park", "Regional Recreation Park", redFillSymbol, regionalRecreationParkValue);
    
        List<UniqueValue> uniqueValuesList = new ArrayList<>();
        uniqueValuesList.add(naturalAreas);
        uniqueValuesList.add(regionalOpenSpace);
        uniqueValuesList.add(localPark);
        uniqueValuesList.add(regionalRecreationPark);
    
        // Create a unique value renderer and set it on the parks and open spaces feature layer.
        // fieldNames is a List, but in this tutorial there is only one item in the list
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("TYPE");
        UniqueValueRenderer openSpacesUniqueValueRenderer =
            new UniqueValueRenderer(fieldNames, uniqueValuesList, "Open Spaces", null);
        featureLayer.setRenderer(openSpacesUniqueValueRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.2f);
      }
    
      private void addTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Create simple line symbols.
        SimpleLineSymbol firstClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 3.0f);
        SimpleLineSymbol secondClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 4.0f);
        SimpleLineSymbol thirdClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 5.0f);
        SimpleLineSymbol fourthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 6.0f);
        SimpleLineSymbol fifthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 7.0f);
    
        // Create five class breaks.
        ClassBreak firstClassBreak =
            new ClassBreak("Under 500", "0 - 500", 0.0, 500.0, firstClassSymbol);
        ClassBreaksRenderer.ClassBreak secondClassBreak =
            new  ClassBreak("501 to 1000", "501 - 1000", 501.0, 1000.0, secondClassSymbol);
        ClassBreak thirdClassBreak =
            new  ClassBreak("1001 to 1500", "1001 - 1500", 1001.0, 1500.0, thirdClassSymbol);
        ClassBreak fourthClassBreak =
            new  ClassBreak("1501 to 2000", "1501 - 2000", 1501.0, 2000.0, fourthClassSymbol);
        ClassBreak fifthClassBreak =
            new ClassBreak("2001 to 2300", "2001 - 2300", 2001.0, 2300.0, fifthClassSymbol);
    
        List<ClassBreak> elevationBreaks = new ArrayList<>();
        elevationBreaks.add(firstClassBreak);
        elevationBreaks.add(secondClassBreak);
        elevationBreaks.add(thirdClassBreak);
        elevationBreaks.add(fourthClassBreak);
        elevationBreaks.add(fifthClassBreak);
    
        // Create a class breaks renderer and set it on the feature layer.
        ClassBreaksRenderer elevationClassBreaksRenderer =
            new ClassBreaksRenderer("ELEV_GAIN", elevationBreaks);
        featureLayer.setRenderer(elevationClassBreaksRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.75f);
    
      }
    
      private void addBikeOnlyTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'Yes'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol bikeTrailSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, BLUE, 2.0f);
        SimpleRenderer bikeTrailRenderer = new SimpleRenderer(bikeTrailSymbol);
        featureLayer.setRenderer(bikeTrailRenderer);
    
      }
    
      private void addNoBikesTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that don't permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'No'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol noBikeTrailSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, RED, 2.0f);
        SimpleRenderer noBikeTrailRenderer =
            new SimpleRenderer(noBikeTrailSymbol);
        featureLayer.setRenderer(noBikeTrailRenderer);
      }
    
      private LabelDefinition makeLabelDefinition(String labelAttribute){
        // Create a new text symbol.
        TextSymbol labelTextSymbol  = new TextSymbol();
        labelTextSymbol.setColor(WHITE);
        labelTextSymbol.setSize(12.0f);
        labelTextSymbol.setHaloColor(RED);
        labelTextSymbol.setHaloWidth(1.0f);
        labelTextSymbol.setFontFamily("Arial");
        labelTextSymbol.setFontStyle(TextSymbol.FontStyle.ITALIC);
        labelTextSymbol.setFontWeight(TextSymbol.FontWeight.NORMAL);
    
        // Create a new Arcade label expression based on the field name.
        ArcadeLabelExpression labelExpression =
            new ArcadeLabelExpression("$feature." + labelAttribute);
    
        // Create and return the label definition.
        return new LabelDefinition(labelExpression, labelTextSymbol);
    
      }
    
      private void addTrailHeadsLayer() {
    
        // Create a trailheads feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trailheads);
    
        // Create a new picture marker symbol that uses the trailhead image.
        PictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbol(trailheadImage);
        pictureMarkerSymbol.setHeight(18.0f);
        pictureMarkerSymbol.setWidth(18.0f);
    
    
        // Create a new simple renderer based on the picture marker symbol.
        SimpleRenderer simpleRenderer = new SimpleRenderer(pictureMarkerSymbol);
    
        // Set the feature layer's renderer, and enable labels.
        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setLabelsEnabled(true);
    
        // Create the label definition.
        LabelDefinition trailHeadsDefinition = makeLabelDefinition("TRL_NAME");
    
        // Add the label definition to the layer's list of label definitions.
        featureLayer.getLabelDefinitions().add(trailHeadsDefinition);
    
      }
    
    }
    

Import headers and define constants

You will add imports and define colors used in this tutorial.

  1. In the IntelliJ IDEA > Project tool window, open src/main/java/com.example.app and click App. Add the following imports, replacing those from the Display a map tutorial.

    App.java
    Use dark colors for code blocks
                                                                                                                                                                                                                                                                                                                       
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0";
      private final String trailheadImage = "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png";
    
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
    
        // set the title and size of the stage and show it
        stage.setTitle("Style a feature layer");
    
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEy";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 72000.0));
    
        addOpenSpaceLayer();
    
        addTrailsLayer();
    
        addBikeOnlyTrailsLayer();
    
        addNoBikesTrailsLayer();
    
        addTrailHeadsLayer();
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
      private FeatureLayer addFeatureLayer(String featureServiceUri){
        // Create a service feature table from a Uri.
        ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(featureServiceUri);
        // Create a feature layer from the service feature table.
        FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
        // Add the feature layer to the map's list of operational layers.
        map.getOperationalLayers().add(featureLayer);
        // return the feature layer
        return featureLayer;
      }
    
      private void addOpenSpaceLayer() {
        // Create a parks and open spaces feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(parksAndOpenSpaces);
    
        // Create fill symbols.
        SimpleFillSymbol purpleFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, PURPLE, null);
        SimpleFillSymbol greenFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, GREEN, null);
        SimpleFillSymbol blueFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, BLUE, null);
        SimpleFillSymbol redFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, RED, null);
    
        // Create a unique value for natural areas, regional open spaces, local parks, and regional recreation parks.
        List<Object> naturalAreasValue = new ArrayList<>();
        naturalAreasValue.add("Natural Areas");
        UniqueValue naturalAreas =
            new UniqueValue("Natural Areas", "Natural Areas", purpleFillSymbol, naturalAreasValue);
    
        List<Object> regionalOpenSpaceValue = new ArrayList<>();
        naturalAreasValue.add("Regional Open Space");
        UniqueValue regionalOpenSpace =
            new UniqueValue("Regional Open Space", "Regional Open Space", greenFillSymbol, regionalOpenSpaceValue);
    
        List<Object> localParkValue = new ArrayList<>();
        localParkValue.add("Local Park");
        UniqueValue localPark =
            new UniqueValue("Local Park", "Local Park", blueFillSymbol, localParkValue);
    
        List<Object> regionalRecreationParkValue = new ArrayList<>();
        regionalRecreationParkValue.add("Regional Recreation Park");
        UniqueValue regionalRecreationPark =
            new UniqueValue("Regional Recreation Park", "Regional Recreation Park", redFillSymbol, regionalRecreationParkValue);
    
        List<UniqueValue> uniqueValuesList = new ArrayList<>();
        uniqueValuesList.add(naturalAreas);
        uniqueValuesList.add(regionalOpenSpace);
        uniqueValuesList.add(localPark);
        uniqueValuesList.add(regionalRecreationPark);
    
        // Create a unique value renderer and set it on the parks and open spaces feature layer.
        // fieldNames is a List, but in this tutorial there is only one item in the list
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("TYPE");
        UniqueValueRenderer openSpacesUniqueValueRenderer =
            new UniqueValueRenderer(fieldNames, uniqueValuesList, "Open Spaces", null);
        featureLayer.setRenderer(openSpacesUniqueValueRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.2f);
      }
    
      private void addTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Create simple line symbols.
        SimpleLineSymbol firstClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 3.0f);
        SimpleLineSymbol secondClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 4.0f);
        SimpleLineSymbol thirdClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 5.0f);
        SimpleLineSymbol fourthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 6.0f);
        SimpleLineSymbol fifthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 7.0f);
    
        // Create five class breaks.
        ClassBreak firstClassBreak =
            new ClassBreak("Under 500", "0 - 500", 0.0, 500.0, firstClassSymbol);
        ClassBreaksRenderer.ClassBreak secondClassBreak =
            new  ClassBreak("501 to 1000", "501 - 1000", 501.0, 1000.0, secondClassSymbol);
        ClassBreak thirdClassBreak =
            new  ClassBreak("1001 to 1500", "1001 - 1500", 1001.0, 1500.0, thirdClassSymbol);
        ClassBreak fourthClassBreak =
            new  ClassBreak("1501 to 2000", "1501 - 2000", 1501.0, 2000.0, fourthClassSymbol);
        ClassBreak fifthClassBreak =
            new ClassBreak("2001 to 2300", "2001 - 2300", 2001.0, 2300.0, fifthClassSymbol);
    
        List<ClassBreak> elevationBreaks = new ArrayList<>();
        elevationBreaks.add(firstClassBreak);
        elevationBreaks.add(secondClassBreak);
        elevationBreaks.add(thirdClassBreak);
        elevationBreaks.add(fourthClassBreak);
        elevationBreaks.add(fifthClassBreak);
    
        // Create a class breaks renderer and set it on the feature layer.
        ClassBreaksRenderer elevationClassBreaksRenderer =
            new ClassBreaksRenderer("ELEV_GAIN", elevationBreaks);
        featureLayer.setRenderer(elevationClassBreaksRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.75f);
    
      }
    
      private void addBikeOnlyTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'Yes'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol bikeTrailSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, BLUE, 2.0f);
        SimpleRenderer bikeTrailRenderer = new SimpleRenderer(bikeTrailSymbol);
        featureLayer.setRenderer(bikeTrailRenderer);
    
      }
    
      private void addNoBikesTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that don't permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'No'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol noBikeTrailSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, RED, 2.0f);
        SimpleRenderer noBikeTrailRenderer =
            new SimpleRenderer(noBikeTrailSymbol);
        featureLayer.setRenderer(noBikeTrailRenderer);
      }
    
      private LabelDefinition makeLabelDefinition(String labelAttribute){
        // Create a new text symbol.
        TextSymbol labelTextSymbol  = new TextSymbol();
        labelTextSymbol.setColor(WHITE);
        labelTextSymbol.setSize(12.0f);
        labelTextSymbol.setHaloColor(RED);
        labelTextSymbol.setHaloWidth(1.0f);
        labelTextSymbol.setFontFamily("Arial");
        labelTextSymbol.setFontStyle(TextSymbol.FontStyle.ITALIC);
        labelTextSymbol.setFontWeight(TextSymbol.FontWeight.NORMAL);
    
        // Create a new Arcade label expression based on the field name.
        ArcadeLabelExpression labelExpression =
            new ArcadeLabelExpression("$feature." + labelAttribute);
    
        // Create and return the label definition.
        return new LabelDefinition(labelExpression, labelTextSymbol);
    
      }
    
      private void addTrailHeadsLayer() {
    
        // Create a trailheads feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trailheads);
    
        // Create a new picture marker symbol that uses the trailhead image.
        PictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbol(trailheadImage);
        pictureMarkerSymbol.setHeight(18.0f);
        pictureMarkerSymbol.setWidth(18.0f);
    
    
        // Create a new simple renderer based on the picture marker symbol.
        SimpleRenderer simpleRenderer = new SimpleRenderer(pictureMarkerSymbol);
    
        // Set the feature layer's renderer, and enable labels.
        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setLabelsEnabled(true);
    
        // Create the label definition.
        LabelDefinition trailHeadsDefinition = makeLabelDefinition("TRL_NAME");
    
        // Add the label definition to the layer's list of label definitions.
        featureLayer.getLabelDefinitions().add(trailHeadsDefinition);
    
      }
    
    }
    
  2. Add static fields to hold the RGB hex value of certain colors. These are the colors you will be assigning to symbols.

    App.java
    Use dark colors for code blocks
    48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 49 50 51 52 53 54 54 53 52 51 50 49 48 47 46 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 44 43 42 41 40 39 38 37 36 35 35 35 35 35 35 35 35 35 35 35 35 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -149
    Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0";
      private final String trailheadImage = "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png";
    
    
      public static void main(String[] args) {
        Application.launch(args);
      }
    
      @Override
      public void start(Stage stage) {
    
        // set the title and size of the stage and show it
        stage.setTitle("Style a feature layer");
    
        stage.setWidth(800);
        stage.setHeight(700);
        stage.show();
    
        // create a JavaFX scene with a stack pane as the root node, and add it to the scene
        StackPane stackPane = new StackPane();
        Scene scene = new Scene(stackPane);
        stage.setScene(scene);
    
        // Note: it is not best practice to store API keys in source code.
        // The API key is referenced here for the convenience of this tutorial.
        String yourApiKey = "YOUR_API_KEy";
        ArcGISRuntimeEnvironment.setApiKey(yourApiKey);
    
        // create a map view to display the map and add it to the stack pane
        mapView = new MapView();
        stackPane.getChildren().add(mapView);
    
        map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
        // set the map on the map view
        mapView.setMap(map);
    
        mapView.setViewpoint(new Viewpoint(34.02700, -118.80543, 72000.0));
    
        addOpenSpaceLayer();
    
        addTrailsLayer();
    
        addBikeOnlyTrailsLayer();
    
        addNoBikesTrailsLayer();
    
        addTrailHeadsLayer();
    
      }
    
      /**
       * Stops and releases all resources used in application.
       */
      @Override
      public void stop() {
        if (mapView != null) {
          mapView.dispose();
        }
      }
    
      private FeatureLayer addFeatureLayer(String featureServiceUri){
        // Create a service feature table from a Uri.
        ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(featureServiceUri);
        // Create a feature layer from the service feature table.
        FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
        // Add the feature layer to the map's list of operational layers.
        map.getOperationalLayers().add(featureLayer);
        // return the feature layer
        return featureLayer;
      }
    
      private void addOpenSpaceLayer() {
        // Create a parks and open spaces feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(parksAndOpenSpaces);
    
        // Create fill symbols.
        SimpleFillSymbol purpleFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, PURPLE, null);
        SimpleFillSymbol greenFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, GREEN, null);
        SimpleFillSymbol blueFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, BLUE, null);
        SimpleFillSymbol redFillSymbol =
            new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, RED, null);
    
        // Create a unique value for natural areas, regional open spaces, local parks, and regional recreation parks.
        List<Object> naturalAreasValue = new ArrayList<>();
        naturalAreasValue.add("Natural Areas");
        UniqueValue naturalAreas =
            new UniqueValue("Natural Areas", "Natural Areas", purpleFillSymbol, naturalAreasValue);
    
        List<Object> regionalOpenSpaceValue = new ArrayList<>();
        naturalAreasValue.add("Regional Open Space");
        UniqueValue regionalOpenSpace =
            new UniqueValue("Regional Open Space", "Regional Open Space", greenFillSymbol, regionalOpenSpaceValue);
    
        List<Object> localParkValue = new ArrayList<>();
        localParkValue.add("Local Park");
        UniqueValue localPark =
            new UniqueValue("Local Park", "Local Park", blueFillSymbol, localParkValue);
    
        List<Object> regionalRecreationParkValue = new ArrayList<>();
        regionalRecreationParkValue.add("Regional Recreation Park");
        UniqueValue regionalRecreationPark =
            new UniqueValue("Regional Recreation Park", "Regional Recreation Park", redFillSymbol, regionalRecreationParkValue);
    
        List<UniqueValue> uniqueValuesList = new ArrayList<>();
        uniqueValuesList.add(naturalAreas);
        uniqueValuesList.add(regionalOpenSpace);
        uniqueValuesList.add(localPark);
        uniqueValuesList.add(regionalRecreationPark);
    
        // Create a unique value renderer and set it on the parks and open spaces feature layer.
        // fieldNames is a List, but in this tutorial there is only one item in the list
        List<String> fieldNames = new ArrayList<>();
        fieldNames.add("TYPE");
        UniqueValueRenderer openSpacesUniqueValueRenderer =
            new UniqueValueRenderer(fieldNames, uniqueValuesList, "Open Spaces", null);
        featureLayer.setRenderer(openSpacesUniqueValueRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.2f);
      }
    
      private void addTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Create simple line symbols.
        SimpleLineSymbol firstClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 3.0f);
        SimpleLineSymbol secondClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 4.0f);
        SimpleLineSymbol thirdClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 5.0f);
        SimpleLineSymbol fourthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 6.0f);
        SimpleLineSymbol fifthClassSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, PURPLE, 7.0f);
    
        // Create five class breaks.
        ClassBreak firstClassBreak =
            new ClassBreak("Under 500", "0 - 500", 0.0, 500.0, firstClassSymbol);
        ClassBreaksRenderer.ClassBreak secondClassBreak =
            new  ClassBreak("501 to 1000", "501 - 1000", 501.0, 1000.0, secondClassSymbol);
        ClassBreak thirdClassBreak =
            new  ClassBreak("1001 to 1500", "1001 - 1500", 1001.0, 1500.0, thirdClassSymbol);
        ClassBreak fourthClassBreak =
            new  ClassBreak("1501 to 2000", "1501 - 2000", 1501.0, 2000.0, fourthClassSymbol);
        ClassBreak fifthClassBreak =
            new ClassBreak("2001 to 2300", "2001 - 2300", 2001.0, 2300.0, fifthClassSymbol);
    
        List<ClassBreak> elevationBreaks = new ArrayList<>();
        elevationBreaks.add(firstClassBreak);
        elevationBreaks.add(secondClassBreak);
        elevationBreaks.add(thirdClassBreak);
        elevationBreaks.add(fourthClassBreak);
        elevationBreaks.add(fifthClassBreak);
    
        // Create a class breaks renderer and set it on the feature layer.
        ClassBreaksRenderer elevationClassBreaksRenderer =
            new ClassBreaksRenderer("ELEV_GAIN", elevationBreaks);
        featureLayer.setRenderer(elevationClassBreaksRenderer);
    
        // Set the layer opacity to semi-transparent.
        featureLayer.setOpacity(0.75f);
    
      }
    
      private void addBikeOnlyTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'Yes'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol bikeTrailSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, BLUE, 2.0f);
        SimpleRenderer bikeTrailRenderer = new SimpleRenderer(bikeTrailSymbol);
        featureLayer.setRenderer(bikeTrailRenderer);
    
      }
    
      private void addNoBikesTrailsLayer() {
        // Create a trails feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trails);
    
        // Write a definition expression to filter for trails that don't permit the use of bikes.
        featureLayer.setDefinitionExpression("USE_BIKE = 'No'");
    
        // Create a simple renderer and set it on the feature layer.
        SimpleLineSymbol noBikeTrailSymbol =
            new SimpleLineSymbol(SimpleLineSymbol.Style.DOT, RED, 2.0f);
        SimpleRenderer noBikeTrailRenderer =
            new SimpleRenderer(noBikeTrailSymbol);
        featureLayer.setRenderer(noBikeTrailRenderer);
      }
    
      private LabelDefinition makeLabelDefinition(String labelAttribute){
        // Create a new text symbol.
        TextSymbol labelTextSymbol  = new TextSymbol();
        labelTextSymbol.setColor(WHITE);
        labelTextSymbol.setSize(12.0f);
        labelTextSymbol.setHaloColor(RED);
        labelTextSymbol.setHaloWidth(1.0f);
        labelTextSymbol.setFontFamily("Arial");
        labelTextSymbol.setFontStyle(TextSymbol.FontStyle.ITALIC);
        labelTextSymbol.setFontWeight(TextSymbol.FontWeight.NORMAL);
    
        // Create a new Arcade label expression based on the field name.
        ArcadeLabelExpression labelExpression =
            new ArcadeLabelExpression("$feature." + labelAttribute);
    
        // Create and return the label definition.
        return new LabelDefinition(labelExpression, labelTextSymbol);
    
      }
    
      private void addTrailHeadsLayer() {
    
        // Create a trailheads feature layer and add it to the map view.
        FeatureLayer featureLayer = addFeatureLayer(trailheads);
    
        // Create a new picture marker symbol that uses the trailhead image.
        PictureMarkerSymbol pictureMarkerSymbol = new PictureMarkerSymbol(trailheadImage);
        pictureMarkerSymbol.setHeight(18.0f);
        pictureMarkerSymbol.setWidth(18.0f);
    
    
        // Create a new simple renderer based on the picture marker symbol.
        SimpleRenderer simpleRenderer = new SimpleRenderer(pictureMarkerSymbol);
    
        // Set the feature layer's renderer, and enable labels.
        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setLabelsEnabled(true);
    
        // Create the label definition.
        LabelDefinition trailHeadsDefinition = makeLabelDefinition("TRL_NAME");
    
        // Add the label definition to the layer's list of label definitions.
        featureLayer.getLabelDefinitions().add(trailHeadsDefinition);
    
      }
    
    }
    

Create a method to add a feature layer

You can add a feature layer from a feature service hosted in ArcGIS. Each feature layer contains features with a single geometry type (point, line, or polygon), and a set of attributes. Once added to the map, feature layers can be symbolized, styled, and labeled in a variety of ways.

Define variables that store feature service URLs used by the app's layers and then create a helper method to add a layer to the map's collection of operational layers. You will use this code throughout the tutorial as you add and symbolize various layers.

  1. Create four static fields of type String: three for accessing feature layers, and a fourth for accessing a static image for use in a picture marker symbol. You will use these resources in future steps.

    App.java
    Use dark colors for code blocks
    55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 56 57 58 59 60 61 62 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 62 61 60 59 58 57 56 55 54 53 53 53 53 53 53 53 53 53 53 53 53 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -131
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    package com.example.app;
    
    import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
    import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
    import com.esri.arcgisruntime.data.ServiceFeatureTable;
    import com.esri.arcgisruntime.layers.FeatureLayer;
    import com.esri.arcgisruntime.mapping.ArcGISMap;
    import com.esri.arcgisruntime.mapping.BasemapStyle;
    import com.esri.arcgisruntime.mapping.Viewpoint;
    import com.esri.arcgisruntime.mapping.labeling.ArcadeLabelExpression;
    import com.esri.arcgisruntime.mapping.view.MapView;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer;
    import com.esri.arcgisruntime.symbology.ClassBreaksRenderer.ClassBreak;
    import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
    import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
    import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
    import com.esri.arcgisruntime.symbology.SimpleRenderer;
    import com.esri.arcgisruntime.symbology.TextSymbol;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
    import com.esri.arcgisruntime.symbology.UniqueValueRenderer.UniqueValue;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class App extends Application {
    
      private MapView mapView;
    
      private ArcGISMap map =new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
    
      // colors for symbols
      private static final int RED = 0xFFFF0000;
      private static final int GREEN = 0xFF00FF00;
      private static final int BLUE = 0xFF0000FF;
      private static final int PURPLE = 0xFF800080;
      private static final int WHITE = 0xFFFFFFFF;
    
      // Application constants used to connect to data and resources.
      private final String parksAndOpenSpaces =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0";
      private final String trails =
          "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0";
      private final String trailheads =