JavaFX is the new de facto standard for desktop Java application for some years now. Although, it already provides lots of typical UI components, there is always demand for other controls with special requirements for the application to be build.
This was also the case in my open-source project SportsTracker, which has been migrated from Swing to JavaFX some time ago. The user of SportsTracker want to see the recorded cycling or running exercises on a map and they also want to be able to replay the track and see the details of the track positions. SportsTracker already had such a map component, but this was still Swing based. Due to missing features and integration problems when using Swing in JavaFX applications (and some not so nice workarounds), I’ve decided to replace the map viewer with a JavaFX map component.
The need for a map viewer is nothing special nowadays, so I’ve searched for existing 3rd party components. As expected, there were some and these two were looking most promising:
- GMapsFX: This component supports Google Maps only. For displaying sporting activities, it’s better to use OpenStreetMap and its layer derivates instead. Furthermore, the developer must accept the Google Terms of Service, they are also not free for commercial applications.
- Gluon Maps: In contrast to GMapsFX, this map component uses OpenStreetMap only and provides basic layering support. Unfortunately, it doesn’t provide the needed controls (zoom, layers, scale) and support for custom markers and tracks. Initial tests has shown that the map viewer contains several bugs, the development is also not very active.
Sadly, none of them matches the SportsTracker requirements, so I needed to create a new map viewer component.
The initial tests were working without major problems, so I’ve decided to create a reusable component and call it:
The implementation was done in Kotlin instead of Java, because this new, but very mature language provides a lot of helpful features, such as:
- Rapid and compact implementation of configuration and value objects by using Properties and Data Classes.
The current feature set of the LeafletMap component is:
- Support for OpenStreetMap, OpenCycleMap, HikeBikeMap, MtbMap and MapBox layers. More can be added easily and the layers can be switched at runtime.
- Configurable zoom, scale and layer controls.
- Supports metric and imperial units.
- Display of nameable markers in multiple colors.
- Display of tracks with automatic fitting zoom.
- Small component library, just about 120 kByte for LeafletMap and 880 kByte for the Kotlin standard library. No other dependencies needed.
Although written in Kotlin, the LeafletMap component API can be used from Java and so from other JVM languages without any problems. The project contains a simple JavaFX demo application written in Kotlin, which demonstrates the usage of the map component with layers, markers and tracks.
The usage of LeafletMap is very simple, here’s the Kotlin code for adding a default map view to the container StackPane
val mapView = LeafletMapView() spMapView.children.add(mapView) mapView.displayMap(MapConfig())
If you need special layers or control configuration, you can define it in the passed
MapConfig object, such as:
mapView.displayMap(MapConfig( layers = listOf(MapLayer.OPENSTREETMAP, MapLayer.HIKE_BIKE_MAP), zoomControlConfig = ZoomControlConfig(true, ControlPosition.BOTTOM_LEFT), scaleControlConfig = ScaleControlConfig(true, ControlPosition.BOTTOM_LEFT, metric = true)))
If you are looking for a Java usage example, take a look at the ExerciseViewer in the SportsTracker application (class
TrackPanelController) for a more complex scenario.
The LeafletMap component is available from the SportsTracker GitHub project sub-page. The initial stable version 1.0.0 of LeafletMap has been released together with SportsTracker 7.4.0. LeafletMap has no dependencies to SportsTracker and can be used easily in other applications. Depending on demand, there will possibly be a separate GitHub project in the future.
LeafletMap is open-source and uses the Apache License, Version 2.0.
Final hint: if you are using Leaflet in your application, make sure to use Java SE 8u131 or higher, this release contains an updated WebKit version and provides a bugfix for a memory leak in the WebView component.