Commit dd1ce7fe83362fb902f85183684bac14c6d6ed9c
1 parent
78935bd622
Exists in
master
and in
1 other branch
add button to switch between real time and static mode
Showing 9 changed files with 70 additions and 25 deletions Side-by-side Diff
- src/main/kotlin/application/controller/MapPanelController.kt
- src/main/kotlin/application/controller/MenuBarController.kt
- src/main/kotlin/application/controller/TimePanel.kt
- src/main/kotlin/application/controller/VesselListPanelController.kt
- src/main/kotlin/application/model/ObservableReplayState.kt
- src/main/kotlin/application/model/ObservableSelectedVessel.kt
- src/main/kotlin/application/model/ObservableVessel.kt
- src/main/kotlin/map/MapDisplayer.kt
- src/main/resources/gui/menuBar.fxml
src/main/kotlin/application/controller/MapPanelController.kt
View file @
dd1ce7f
| ... | ... | @@ -16,12 +16,12 @@ |
| 16 | 16 | |
| 17 | 17 | private val mapView = LeafletMapView() |
| 18 | 18 | |
| 19 | - | |
| 20 | 19 | override fun initialize(location: URL?, resources: ResourceBundle?) { |
| 21 | 20 | mapView.displayMap(MapConfig()) |
| 22 | 21 | setObservableVesselListener() |
| 23 | 22 | setObservableSelectedVesselListener() |
| 24 | 23 | setStateListener() |
| 24 | + setObservableIsReplayState() | |
| 25 | 25 | observableCurrentTime() |
| 26 | 26 | |
| 27 | 27 | map.children.add(mapView) |
| ... | ... | @@ -31,8 +31,8 @@ |
| 31 | 31 | private fun setStateListener() { |
| 32 | 32 | observableMapState.listeners.add(object : StateListener { |
| 33 | 33 | override fun onValueChanged(newValue: MapState) { |
| 34 | - if (observableSelectedVessel.vessel.mmsi != null) { | |
| 35 | - updateMap(observableSelectedVessel.vessel.mmsi!!) | |
| 34 | + if (observableSelectedVessel.value.mmsi != null) { | |
| 35 | + updateMap(observableSelectedVessel.value.mmsi!!) | |
| 36 | 36 | } else { |
| 37 | 37 | updateMap() |
| 38 | 38 | } |
| ... | ... | @@ -43,8 +43,8 @@ |
| 43 | 43 | private fun observableCurrentTime() { |
| 44 | 44 | observableCurrentTime.listeners.add(object : CurrentTime { |
| 45 | 45 | override fun onValueChanged(newValue: Int) { |
| 46 | - if (observableSelectedVessel.vessel.mmsi != null) { | |
| 47 | - updateMap(observableSelectedVessel.vessel.mmsi!!) | |
| 46 | + if (observableSelectedVessel.value.mmsi != null) { | |
| 47 | + updateMap(observableSelectedVessel.value.mmsi!!) | |
| 48 | 48 | } else { |
| 49 | 49 | updateMap() |
| 50 | 50 | } |
| ... | ... | @@ -88,6 +88,18 @@ |
| 88 | 88 | observableVessel.listeners.add(object : MessageListener { |
| 89 | 89 | override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { |
| 90 | 90 | updateMap() |
| 91 | + } | |
| 92 | + }) | |
| 93 | + } | |
| 94 | + | |
| 95 | + private fun setObservableIsReplayState() { | |
| 96 | + observableIsReplayState.listeners.add(object: ReplayState { | |
| 97 | + override fun onValueChanged(newValue: Boolean) { | |
| 98 | + if (observableSelectedVessel.value.mmsi != null) { | |
| 99 | + updateMap(observableSelectedVessel.value.mmsi!!) | |
| 100 | + } else { | |
| 101 | + updateMap() | |
| 102 | + } | |
| 91 | 103 | } |
| 92 | 104 | }) |
| 93 | 105 | } |
src/main/kotlin/application/controller/MenuBarController.kt
View file @
dd1ce7f
| ... | ... | @@ -2,15 +2,13 @@ |
| 2 | 2 | |
| 3 | 3 | import application.model.MapState.* |
| 4 | 4 | import application.model.createVesselCollection |
| 5 | +import application.model.observableIsReplayState | |
| 5 | 6 | import application.model.observableMapState |
| 6 | 7 | import application.model.observableVessel |
| 7 | 8 | import javafx.event.EventHandler |
| 8 | 9 | import javafx.fxml.FXML |
| 9 | 10 | import javafx.fxml.Initializable |
| 10 | -import javafx.scene.control.Alert | |
| 11 | -import javafx.scene.control.CheckMenuItem | |
| 12 | -import javafx.scene.control.MenuBar | |
| 13 | -import javafx.scene.control.MenuItem | |
| 11 | +import javafx.scene.control.* | |
| 14 | 12 | import javafx.stage.FileChooser |
| 15 | 13 | import java.net.URL |
| 16 | 14 | import java.util.* |
| ... | ... | @@ -32,6 +30,9 @@ |
| 32 | 30 | @FXML |
| 33 | 31 | var heatMap: CheckMenuItem = CheckMenuItem() |
| 34 | 32 | |
| 33 | + @FXML | |
| 34 | + var activateReplayButton: RadioMenuItem = RadioMenuItem() | |
| 35 | + | |
| 35 | 36 | override fun initialize(location: URL?, resources: ResourceBundle?) { |
| 36 | 37 | |
| 37 | 38 | setOnActionImportButton() |
| 38 | 39 | |
| ... | ... | @@ -39,11 +40,18 @@ |
| 39 | 40 | setOnActionAllMessageButton() |
| 40 | 41 | setOnActionClusteredMessageButton() |
| 41 | 42 | setOnActionHeatMapButton() |
| 43 | + setOnActionActivateReplayButton() | |
| 42 | 44 | observableMapState.state = CLUSTERED_MESSAGES |
| 43 | 45 | allMessages.isSelected = false |
| 44 | 46 | clusteredMessage.isSelected = true |
| 45 | 47 | heatMap.isSelected = false |
| 46 | 48 | |
| 49 | + } | |
| 50 | + | |
| 51 | + private fun setOnActionActivateReplayButton() { | |
| 52 | + activateReplayButton.onAction = EventHandler { | |
| 53 | + observableIsReplayState.value = activateReplayButton.isSelected | |
| 54 | + } | |
| 47 | 55 | } |
| 48 | 56 | |
| 49 | 57 | private fun setOnActionImportButton() { |
src/main/kotlin/application/controller/TimePanel.kt
View file @
dd1ce7f
| ... | ... | @@ -24,14 +24,14 @@ |
| 24 | 24 | override fun initialize(location: URL?, resources: ResourceBundle?) { |
| 25 | 25 | setSliderMinMax() |
| 26 | 26 | setSliderListener() |
| 27 | - | |
| 28 | - | |
| 27 | + disableAllButton() | |
| 28 | + setDisable() | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | private fun setSliderMinMax() { |
| 32 | 32 | timeSlider.min = 0.0 |
| 33 | 33 | timeSlider.max = 0.0 |
| 34 | - observableVessel.listeners.add(object : MessageListener{ | |
| 34 | + observableVessel.listeners.add(object : MessageListener { | |
| 35 | 35 | override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { |
| 36 | 36 | timeSlider.max = Vessel.maxTime.toDouble() |
| 37 | 37 | timeSlider.min = Vessel.minTime.toDouble() |
| ... | ... | @@ -43,6 +43,30 @@ |
| 43 | 43 | timeSlider.valueProperty().addListener { _, _, newValue -> |
| 44 | 44 | observableCurrentTime.value = newValue.toInt() |
| 45 | 45 | } |
| 46 | + } | |
| 47 | + | |
| 48 | + private fun disableAllButton() { | |
| 49 | + timeStop.isDisable = true | |
| 50 | + timeSlider.isDisable = true | |
| 51 | + timePlay.isDisable = true | |
| 52 | + } | |
| 53 | + | |
| 54 | + private fun unableAllButton() { | |
| 55 | + timeStop.isDisable = false | |
| 56 | + timeSlider.isDisable = false | |
| 57 | + timePlay.isDisable = false | |
| 58 | + } | |
| 59 | + | |
| 60 | + private fun setDisable() { | |
| 61 | + observableIsReplayState.listeners.add(object : ReplayState { | |
| 62 | + override fun onValueChanged(newValue: Boolean) { | |
| 63 | + if (observableIsReplayState.value) { | |
| 64 | + unableAllButton() | |
| 65 | + } else { | |
| 66 | + disableAllButton() | |
| 67 | + } | |
| 68 | + } | |
| 69 | + }) | |
| 46 | 70 | } |
| 47 | 71 | |
| 48 | 72 | } |
src/main/kotlin/application/controller/VesselListPanelController.kt
View file @
dd1ce7f
| ... | ... | @@ -30,9 +30,9 @@ |
| 30 | 30 | observableVessel.listeners.add(this) |
| 31 | 31 | shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> |
| 32 | 32 | if (newValue == null) { |
| 33 | - observableSelectedVessel.vessel = Vessel(null) | |
| 33 | + observableSelectedVessel.value = Vessel(null) | |
| 34 | 34 | } else { |
| 35 | - observableSelectedVessel.vessel = observableVessel.vessels[newValue]!! | |
| 35 | + observableSelectedVessel.value = observableVessel.vessels[newValue]!! | |
| 36 | 36 | } |
| 37 | 37 | } |
| 38 | 38 | setCellFactory() |
src/main/kotlin/application/model/ObservableReplayState.kt
View file @
dd1ce7f
src/main/kotlin/application/model/ObservableSelectedVessel.kt
View file @
dd1ce7f
| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | class ObservableSelectedVessel { |
| 6 | 6 | val listeners: MutableList<SelectedVesselListener> = mutableListOf() |
| 7 | 7 | |
| 8 | - var vessel: Vessel by Delegates.observable( | |
| 8 | + var value: Vessel by Delegates.observable( | |
| 9 | 9 | initialValue = Vessel(null), |
| 10 | 10 | onChange = { _, _, new -> |
| 11 | 11 | run { |
src/main/kotlin/application/model/ObservableVessel.kt
View file @
dd1ce7f
src/main/kotlin/map/MapDisplayer.kt
View file @
dd1ce7f
| ... | ... | @@ -69,9 +69,9 @@ |
| 69 | 69 | observableVessel.vessels.forEach { (_, value) -> |
| 70 | 70 | value.messages.forEach { (_, message) -> |
| 71 | 71 | if (selectedMMSI == message.mmsi.value) { |
| 72 | - map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)") | |
| 72 | + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap))") | |
| 73 | 73 | } else { |
| 74 | - map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") | |
| 74 | + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))") | |
| 75 | 75 | } |
| 76 | 76 | } |
| 77 | 77 | } |
| ... | ... | @@ -113,7 +113,7 @@ |
| 113 | 113 | observableVessel.vessels.forEach { (_, value) -> |
| 114 | 114 | value.messages.forEach { (_, message) -> |
| 115 | 115 | if (selectedMMSI == message.mmsi.value) { |
| 116 | - map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") | |
| 116 | + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));") | |
| 117 | 117 | } else { |
| 118 | 118 | map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") |
| 119 | 119 | } |
| ... | ... | @@ -157,7 +157,7 @@ |
| 157 | 157 | observableVessel.vessels.forEach { (_, value) -> |
| 158 | 158 | value.messages.forEach { (_, message) -> |
| 159 | 159 | if (selectedMMSI == message.mmsi.value) { |
| 160 | - map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") | |
| 160 | + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));") | |
| 161 | 161 | } else { |
| 162 | 162 | map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") |
| 163 | 163 | } |
src/main/resources/gui/menuBar.fxml
View file @
dd1ce7f
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | <?import javafx.scene.control.*?> |
| 4 | 4 | |
| 5 | -<MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MenuBarController"> | |
| 5 | +<MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MenuBarController"> | |
| 6 | 6 | <menus> |
| 7 | 7 | <Menu mnemonicParsing="false" text="File"> |
| 8 | 8 | <items> |
| 9 | 9 | |
| ... | ... | @@ -13,11 +13,12 @@ |
| 13 | 13 | <items> |
| 14 | 14 | <Menu mnemonicParsing="false" text="Map selected"> |
| 15 | 15 | <items> |
| 16 | - <CheckMenuItem mnemonicParsing="false" text="All messages" fx:id="allMessages"/> | |
| 17 | - <CheckMenuItem mnemonicParsing="false" text="Clustered messages" fx:id="clusteredMessage"/> | |
| 18 | - <CheckMenuItem mnemonicParsing="false" text="Heat map" fx:id="heatMap"/> | |
| 16 | + <CheckMenuItem fx:id="allMessages" mnemonicParsing="false" text="All messages" /> | |
| 17 | + <CheckMenuItem fx:id="clusteredMessage" mnemonicParsing="false" text="Clustered messages" /> | |
| 18 | + <CheckMenuItem fx:id="heatMap" mnemonicParsing="false" text="Heat map" /> | |
| 19 | 19 | </items> |
| 20 | 20 | </Menu> |
| 21 | + <RadioMenuItem fx:id="activateReplayButton" mnemonicParsing="false" text="Unspecified Action" /> | |
| 21 | 22 | </items> |
| 22 | 23 | </Menu> |
| 23 | 24 | <Menu mnemonicParsing="false" text="Help"> |