Commit e220e082b538d95eae8e1c1c23879c90ff0bcde6

Authored by lsagona
1 parent dd1ce7fe83
Exists in master and in 1 other branch dev

graph binded to slider

removed useless start and stop button

Showing 8 changed files with 385 additions and 161 deletions Inline Diff

build.gradle View file @ e220e08
plugins { 1 1 plugins {
id 'java' 2 2 id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.3.72' 3 3 id 'org.jetbrains.kotlin.jvm' version '1.3.72'
} 4 4 }
5 5
group 'marivisu' 6 6 group 'marivisu'
version '1.0-SNAPSHOT' 7 7 version '1.0-SNAPSHOT'
8 8
repositories { 9 9 repositories {
mavenCentral() 10 10 mavenCentral()
maven { 11 11 maven {
url "https://jitpack.io" 12 12 url "https://jitpack.io"
} 13 13 }
} 14 14 }
15 15
dependencies { 16 16 dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" 17 17 implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'org.jfxtras:jmetro:8.6.9' 18 18 implementation 'org.jfxtras:jmetro:8.6.9'
implementation 'org.slf4j:slf4j-api:1.7.30' 19 19 implementation 'org.slf4j:slf4j-api:1.7.30'
20 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
testCompile group: 'junit', name: 'junit', version: '4.12' 20 21 testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' 21 22 testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' 22 23 compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3'
compile 'com.github.jasrodis:javafx-dataviewer-wrapper:-SNAPSHOT' 23 24 compile 'com.github.jasrodis:javafx-dataviewer-wrapper:-SNAPSHOT'
} 24 25 }
25 26
task run(type: JavaExec) { 26 27 task run(type: JavaExec) {
main = 'application.App' 27 28 main = 'application.App'
classpath = sourceSets.main.runtimeClasspath 28 29 classpath = sourceSets.main.runtimeClasspath
} 29 30 }
30 31
compileKotlin { 31 32 compileKotlin {
src/main/kotlin/application/App.kt View file @ e220e08
@file:JvmName("App") 1 1 @file:JvmName("App")
2 2
package application 3 3 package application
4 4
import javafx.application.Application 5 5 import javafx.application.Application
import javafx.application.Platform 6 6 import javafx.application.Platform
import javafx.event.EventHandler 7 7 import javafx.event.EventHandler
import javafx.fxml.FXMLLoader 8 8 import javafx.fxml.FXMLLoader
import javafx.scene.Parent 9 9 import javafx.scene.Parent
import javafx.scene.Scene 10 10 import javafx.scene.Scene
import javafx.stage.Stage 11 11 import javafx.stage.Stage
import jfxtras.styles.jmetro.JMetro 12 12 import jfxtras.styles.jmetro.JMetro
import jfxtras.styles.jmetro.Style 13 13 import jfxtras.styles.jmetro.Style
import kotlin.system.exitProcess 14 14 import kotlin.system.exitProcess
15 15
class App : Application() { 16 16 class App : Application() {
var style: Style = Style.LIGHT 17 17 var style: Style = Style.LIGHT
18 18
override fun start(primaryStage: Stage?) { 19 19 override fun start(primaryStage: Stage?) {
20 20
val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml")) 21 21 val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml"))
val parent: Parent = fxmlLoader.load() 22 22 val parent: Parent = fxmlLoader.load()
val scene = Scene(parent) 23 23 val scene = Scene(parent)
JMetro(scene, style) 24 24 JMetro(scene, style)
primaryStage!!.scene = scene 25 25 primaryStage!!.scene = scene
primaryStage.title = "Maritime Visualisation" 26 26 primaryStage.title = "Maritime Visualisation"
primaryStage.onCloseRequest = EventHandler { closeApplication() } 27 27 primaryStage.onCloseRequest = EventHandler { closeApplication() }
primaryStage.show() 28 28 primaryStage.show()
} 29 29 }
30 30
private fun closeApplication() { 31 31 private fun closeApplication() {
32
Platform.exit() 32 33 Platform.exit()
exitProcess(0) 33 34 exitProcess(0)
} 34 35 }
35 36
src/main/kotlin/application/controller/DataPanelController.kt View file @ e220e08
package application.controller 1 1 package application.controller
2 2
import application.model.* 3 3 import application.model.*
import javafx.collections.FXCollections 4 4 import javafx.collections.FXCollections
import javafx.collections.ObservableList 5 5 import javafx.collections.ObservableList
import javafx.fxml.FXML 6 6 import javafx.fxml.FXML
import javafx.fxml.Initializable 7 7 import javafx.fxml.Initializable
import javafx.scene.control.ListCell 8 8 import javafx.scene.control.ListCell
import javafx.scene.control.ListView 9 9 import javafx.scene.control.ListView
10 import kotlinx.coroutines.GlobalScope
11 import kotlinx.coroutines.launch
import org.charts.dataviewer.api.config.DataViewerConfiguration 10 12 import org.charts.dataviewer.api.config.DataViewerConfiguration
import org.charts.dataviewer.api.data.PlotData 11 13 import org.charts.dataviewer.api.data.PlotData
import org.charts.dataviewer.api.trace.ScatterTrace 12 14 import org.charts.dataviewer.api.trace.ScatterTrace
import org.charts.dataviewer.javafx.JavaFxDataViewer 13 15 import org.charts.dataviewer.javafx.JavaFxDataViewer
import org.charts.dataviewer.utils.TraceColour 14 16 import org.charts.dataviewer.utils.TraceColour
import org.charts.dataviewer.utils.TraceVisibility 15 17 import org.charts.dataviewer.utils.TraceVisibility
import java.net.URL 16 18 import java.net.URL
import java.util.* 17 19 import java.util.*
18 20
19 21
class DataPanelController : Initializable, SelectedVesselListener { 20 22 class DataPanelController : Initializable, SelectedVesselListener {
private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList() 21 23 private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList()
private lateinit var timeData: ArrayList<MessageData?> 22 24 private lateinit var timeData: ArrayList<MessageData?>
23 25
26 private val latitude: ArrayList<MessageData?> = arrayListOf()
27 private val longitude: ArrayList<MessageData?> = arrayListOf()
28 private val speedOverGround: ArrayList<MessageData?> = arrayListOf()
29 private val courseOverGround: ArrayList<MessageData?> = arrayListOf()
30 private val heading: ArrayList<MessageData?> = arrayListOf()
31 private val vesselName: ArrayList<MessageData?> = arrayListOf()
32 private val imo: ArrayList<MessageData?> = arrayListOf()
33 private val callSign: ArrayList<MessageData?> = arrayListOf()
34 private val vesselType: ArrayList<MessageData?> = arrayListOf()
35 private val status: ArrayList<MessageData?> = arrayListOf()
36 private val length: ArrayList<MessageData?> = arrayListOf()
37 private val width: ArrayList<MessageData?> = arrayListOf()
38 private val draft: ArrayList<MessageData?> = arrayListOf()
39 private val cargo: ArrayList<MessageData?> = arrayListOf()
24 40
41 private var selectedItem: Pair<String, ArrayList<MessageData?>>? = null
42
@FXML 25 43 @FXML
var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>() 26 44 var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>()
27 45
@FXML 28 46 @FXML
var dataViewer = JavaFxDataViewer() 29 47 var dataViewer = JavaFxDataViewer()
30 48
49 private val plotData = PlotData()
50 private val config = DataViewerConfiguration()
31 51
override fun initialize(location: URL?, resources: ResourceBundle?) { 32 52 override fun initialize(location: URL?, resources: ResourceBundle?) {
setObservableSelectedVesselListener() 33 53 setObservableSelectedVesselListener()
dataListView.items = dataList 34 54 dataListView.items = dataList
35 55
36 56
val plotData = PlotData() 37 57
val config = DataViewerConfiguration() 38
config.showLegend(true) 39 58 config.showLegend(true)
config.setLegendInsidePlot(false) 40 59 config.setLegendInsidePlot(false)
41 60
61 setObservableCurrentTimeListener()
62
dataListView.setCellFactory { 42 63 dataListView.setCellFactory {
object : ListCell<Pair<String, ArrayList<MessageData?>>?>() { 43 64 object : ListCell<Pair<String, ArrayList<MessageData?>>?>() {
override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) { 44 65 override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) {
super.updateItem(item, empty) 45 66 super.updateItem(item, empty)
text = if (empty) { 46 67 text = if (empty) {
null 47 68 null
} else { 48 69 } else {
item?.first 49 70 item?.first
} 50 71 }
} 51 72 }
} 52 73 }
} 53 74 }
54 75
dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> 55 76 dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
if (newValue == null) { 56 77 selectedItem = newValue
plotData.allTraces.clear() 57 78 plot(newValue)
config.setxAxisTitle("") 58 79 }
config.setyAxisTitle("") 59
dataViewer.updateConfiguration(config) 60
61 80
dataViewer.resetPlot() 62 81 plotData.allTraces.clear()
82 config.setxAxisTitle("")
83 config.setyAxisTitle("")
84 config.plotTitle = ""
85 dataViewer.updateConfiguration(config)
86 dataViewer.updatePlot(plotData)
87 initDataList()
63 88
return@addListener 64 89
90 }
91
92 private fun plot() {
93 if (selectedItem != null) {
94 GlobalScope.launch {
95 plot(selectedItem)
} 65 96 }
97 }
98 }
66 99
val getValueVisitorX = GetValueVisitor() 67 100 private fun plot(data: Pair<String, ArrayList<MessageData?>>?) {
val getValueVisitorY = GetValueVisitor() 68 101 if (data == null) {
102 plotData.allTraces.clear()
103 config.setxAxisTitle("")
104 config.setyAxisTitle("")
105 dataViewer.updateConfiguration(config)
69 106
val arrayListStringX = arrayListOf<String>() 70 107 dataViewer.resetPlot()
val arrayListDoubleX = arrayListOf<Double>() 71
val arrayListStringY = arrayListOf<String>() 72
val arrayListDoubleY = arrayListOf<Double>() 73
74 108
for (x in 0 until newValue.second.size) { 75 109 return
timeData[x]?.accept(getValueVisitorX) 76 110 }
newValue.second[x]?.accept(getValueVisitorY) 77
78 111
if (getValueVisitorY.value.toDoubleOrNull() == null) { 79 112 val getValueVisitorX = GetValueVisitor()
arrayListStringX.add(getValueVisitorX.value) 80 113 val getValueVisitorY = GetValueVisitor()
arrayListStringY.add(getValueVisitorY.value) 81
} else { 82
arrayListStringX.add(getValueVisitorX.value) 83
arrayListDoubleY.add(getValueVisitorY.value.toDouble()) 84
} 85
} 86
87 114
val scatterTrace = ScatterTrace<Any>() 88 115 val arrayListStringX = arrayListOf<String>()
scatterTrace.traceColour = TraceColour.RED 89 116 // val arrayListDoubleX = arrayListOf<Double>()
scatterTrace.traceVisibility = TraceVisibility.TRUE 90 117 val arrayListStringY = arrayListOf<String>()
118 val arrayListDoubleY = arrayListOf<Double>()
91 119
val serieStringX: Array<String> = arrayListStringX.toTypedArray() 92 120 for (x in 0 until timeData.size) {
// val serieDoubleX: Array<Double> = arrayListDoubleX.toTypedArray() 93 121 timeData[x]?.accept(getValueVisitorX)
val serieStringY: Array<String> = arrayListStringY.toTypedArray() 94 122 data.second[x]?.accept(getValueVisitorY)
val serieDoubleY: Array<Double> = arrayListDoubleY.toTypedArray() 95
96 123
if (getValueVisitorY.value.toDoubleOrNull() == null) { 97 124 if (getValueVisitorY.value.toDoubleOrNull() == null) {
scatterTrace.setxArray(serieStringX) 98 125 arrayListStringX.add(getValueVisitorX.value)
scatterTrace.setyArray(serieStringY) 99 126 arrayListStringY.add(getValueVisitorY.value)
} else { 100 127 } else {
scatterTrace.setxArray(serieStringX) 101 128 arrayListStringX.add(getValueVisitorX.value)
scatterTrace.setyArray(serieDoubleY) 102 129 arrayListDoubleY.add(getValueVisitorY.value.toDouble())
} 103 130 }
131 }
104 132
config.plotTitle = "" 105 133 val scatterTrace = ScatterTrace<Any>()
config.setxAxisTitle("Time (s)") 106 134 scatterTrace.traceColour = TraceColour.RED
config.setyAxisTitle(newValue.first) 107 135 scatterTrace.traceVisibility = TraceVisibility.TRUE
dataViewer.resetPlot() 108
plotData.allTraces.clear() 109
plotData.addTrace(scatterTrace) 110
dataViewer.updateConfiguration(config) 111
dataViewer.updatePlot(plotData) 112
113 136
137 val serieStringX: Array<String> = arrayListStringX.toTypedArray()
138 // val serieDoubleX: Array<Double> = arrayListDoubleX.toTypedArray()
139 val serieStringY: Array<String> = arrayListStringY.toTypedArray()
140 val serieDoubleY: Array<Double> = arrayListDoubleY.toTypedArray()
141
142 if (getValueVisitorY.value.toDoubleOrNull() == null) {
143 scatterTrace.setxArray(serieStringX)
144 scatterTrace.setyArray(serieStringY)
145 } else {
146 scatterTrace.setxArray(serieStringX)
147 scatterTrace.setyArray(serieDoubleY)
} 114 148 }
115 149
plotData.allTraces.clear() 116
config.setxAxisTitle("") 117
config.setyAxisTitle("") 118
config.plotTitle = "" 119 150 config.plotTitle = ""
151 config.setxAxisTitle("Time (s)")
152 config.setyAxisTitle(data.first)
153 dataViewer.resetPlot()
154 plotData.allTraces.clear()
155 plotData.addTrace(scatterTrace)
dataViewer.updateConfiguration(config) 120 156 dataViewer.updateConfiguration(config)
dataViewer.updatePlot(plotData) 121 157 dataViewer.updatePlot(plotData)
122 158
} 123 159 }
124 160
161
private fun setObservableSelectedVesselListener() { 125 162 private fun setObservableSelectedVesselListener() {
observableSelectedVessel.listeners.add(this) 126 163 observableSelectedVessel.listeners.add(this)
} 127 164 }
128 165
private fun populateTime(vessel: Vessel): ArrayList<MessageData?> { 129 166 private fun populateTime(vessel: Vessel): ArrayList<MessageData?> {
val allTime: ArrayList<MessageData?> = vessel.getAllTime() 130 167 return if (observableIsReplayState.value) {
allTime.sortBy { (it as Time).value } 131 168 vessel.getAllTimeBeforeSelectedTime()
132 169 } else {
return allTime 133 170 vessel.getAllTime()
171 }
} 134 172 }
135 173
private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> { 136
val allLatitude: ArrayList<MessageData?> = vessel.getAllLatitude() 137
allLatitude.sortBy { (it as Latitude).value } 138
139 174
return allLatitude 140 175 private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> {
176 return if (observableIsReplayState.value) {
177 vessel.getAllLatitudeBeforeSelectedTime()
178 } else {
179 vessel.getAllLatitude()
180 }
} 141 181 }
142 182
private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> { 143 183 private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> {
val allLongitude: ArrayList<MessageData?> = vessel.getAllLongitude() 144 184 return if (observableIsReplayState.value) {
allLongitude.sortBy { (it as Longitude).value } 145 185 vessel.getAllLongitudeBeforeSelectedTime()
146 186 } else {
return allLongitude 147 187 vessel.getAllLongitude()
188 }
} 148 189 }
149 190
private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> { 150 191 private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> {
val allSpeedOverGround: ArrayList<MessageData?> = vessel.getAllSpeedOverGround() 151 192 return if (observableIsReplayState.value) {
allSpeedOverGround.sortBy { (it as SpeedOverGround).value } 152 193 vessel.getAllSpeedOverGroundBeforeSelectedTime()
153 194 } else {
return allSpeedOverGround 154 195 vessel.getAllSpeedOverGround()
196 }
} 155 197 }
156 198
private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> { 157 199 private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> {
val allCourseOverGround: ArrayList<MessageData?> = vessel.getAllCourseOverGround() 158 200 return if (observableIsReplayState.value) {
allCourseOverGround.sortBy { (it as CourseOverGround).value } 159 201 vessel.getAllCourseOverGroundBeforeSelectedTime()
160 202 } else {
return allCourseOverGround 161 203 vessel.getAllCourseOverGround()
204 }
} 162 205 }
163 206
private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> { 164 207 private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> {
val allHeading: ArrayList<MessageData?> = vessel.getAllHeading() 165 208 return if (observableIsReplayState.value) {
allHeading.sortBy { (it as Heading).value } 166 209 vessel.getAllHeadingBeforeSelectedTime()
167 210 } else {
return allHeading 168 211 vessel.getAllHeading()
212 }
} 169 213 }
170 214
private fun populateVesselName(vessel: Vessel): ArrayList<MessageData?> { 171 215 private fun populateVesselName(vessel: Vessel): ArrayList<MessageData?> {
val allVesselName: ArrayList<MessageData?> = vessel.getAllVesselName() 172 216 return if (observableIsReplayState.value) {
allVesselName.sortBy { (it as VesselName).value } 173 217 vessel.getAllVesselNameBeforeSelectedTime()
174 218 } else {
return allVesselName 175 219 vessel.getAllVesselName()
220 }
} 176 221 }
177 222
private fun populateIMO(vessel: Vessel): ArrayList<MessageData?> { 178 223 private fun populateIMO(vessel: Vessel): ArrayList<MessageData?> {
val allIMO: ArrayList<MessageData?> = vessel.getAllIMO() 179 224 return if (observableIsReplayState.value) {
allIMO.sortBy { (it as IMO).value } 180 225 vessel.getAllIMOBeforeSelectedTime()
181 226 } else {
return allIMO 182 227 vessel.getAllIMO()
228 }
} 183 229 }
184 230
private fun populateCallSign(vessel: Vessel): ArrayList<MessageData?> { 185 231 private fun populateCallSign(vessel: Vessel): ArrayList<MessageData?> {
val allCallSign: ArrayList<MessageData?> = vessel.getAllCallSign() 186 232 return if (observableIsReplayState.value) {
allCallSign.sortBy { (it as CallSign).value } 187 233 vessel.getAllCallSignBeforeSelectedTime()
188 234 } else {
return allCallSign 189 235 vessel.getAllCallSign()
236 }
} 190 237 }
191 238
private fun populateVesselType(vessel: Vessel): ArrayList<MessageData?> { 192 239 private fun populateVesselType(vessel: Vessel): ArrayList<MessageData?> {
val allVesselType: ArrayList<MessageData?> = vessel.getAllVesselType() 193 240 return if (observableIsReplayState.value) {
allVesselType.sortBy { (it as VesselType).value } 194 241 vessel.getAllVesselTypeBeforeSelectedTime()
195 242 } else {
return allVesselType 196 243 vessel.getAllVesselType()
244 }
} 197 245 }
198 246
private fun populateStatus(vessel: Vessel): ArrayList<MessageData?> { 199 247 private fun populateStatus(vessel: Vessel): ArrayList<MessageData?> {
val allStatus: ArrayList<MessageData?> = vessel.getAllStatus() 200 248 return if (observableIsReplayState.value) {
allStatus.sortBy { (it as Status).value } 201 249 vessel.getAllStatusBeforeSelectedTime()
202 250 } else {
return allStatus 203 251 vessel.getAllStatus()
252 }
} 204 253 }
205 254
private fun populateLength(vessel: Vessel): ArrayList<MessageData?> { 206 255 private fun populateLength(vessel: Vessel): ArrayList<MessageData?> {
val allLength: ArrayList<MessageData?> = vessel.getAllLength() 207 256 return if (observableIsReplayState.value) {
allLength.sortBy { (it as Length).value } 208 257 vessel.getAllLengthBeforeSelectedTime()
209 258 } else {
return allLength 210 259 vessel.getAllLength()
260 }
} 211 261 }
212 262
private fun populateWidth(vessel: Vessel): ArrayList<MessageData?> { 213 263 private fun populateWidth(vessel: Vessel): ArrayList<MessageData?> {
val allWidth: ArrayList<MessageData?> = vessel.getAllWidth() 214 264 return if (observableIsReplayState.value) {
allWidth.sortBy { (it as Width).value } 215 265 vessel.getAllWidthBeforeSelectedTime()
216 266 } else {
return allWidth 217 267 vessel.getAllWidth()
268 }
} 218 269 }
219 270
private fun populateDraft(vessel: Vessel): ArrayList<MessageData?> { 220 271 private fun populateDraft(vessel: Vessel): ArrayList<MessageData?> {
val allDraft: ArrayList<MessageData?> = vessel.getAllDraft() 221 272 return if (observableIsReplayState.value) {
allDraft.sortBy { (it as Draft).value } 222 273 vessel.getAllDraftBeforeSelectedTime()
223 274 } else {
return allDraft 224 275 vessel.getAllDraft()
276 }
} 225 277 }
226 278
private fun populateCargo(vessel: Vessel): ArrayList<MessageData?> { 227 279 private fun populateCargo(vessel: Vessel): ArrayList<MessageData?> {
val allCargo: ArrayList<MessageData?> = vessel.getAllCargo() 228 280 return if (observableIsReplayState.value) {
allCargo.sortBy { (it as Cargo).value } 229 281 vessel.getAllCargoBeforeSelectedTime()
230 282 } else {
return allCargo 231 283 vessel.getAllCargo()
284 }
} 232 285 }
233 286
private fun populateDataList(vessel: Vessel) { 234 287 private fun initDataList() {
val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>() 235 288 val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>()
236 289
290 data.add(Pair("Latitude", latitude))
291 data.add(Pair("Longitude", longitude))
292 data.add(Pair("Speed Over Ground", speedOverGround))
293 data.add(Pair("Course Over Ground", courseOverGround))
294 data.add(Pair("Heading", heading))
295 data.add(Pair("Vessel Name", vesselName))
296 data.add(Pair("IMO", imo))
297 data.add(Pair("Call Sign", callSign))
298 data.add(Pair("Vessel Type", vesselType))
299 data.add(Pair("Status", status))
300 data.add(Pair("Length", length))
301 data.add(Pair("Width", width))
302 data.add(Pair("Draft", draft))
303 data.add(Pair("Cargo", cargo))
304
305 dataList.addAll(data)
306 }
307
308 private fun updateDataList(vessel: Vessel) {
timeData = populateTime(vessel) 237 309 timeData = populateTime(vessel)
238 310
data.add(Pair("Latitude", populateLatitude(vessel))) 239 311 latitude.clear()
312 latitude.addAll(populateLatitude(vessel))
240 313
data.add(Pair("Longitude", populateLongitude(vessel))) 241 314 longitude.clear()
315 longitude.addAll(populateLongitude(vessel))
242 316
data.add(Pair("Speed Over Ground", populateSpeedOverGround(vessel))) 243 317 speedOverGround.clear()
318 speedOverGround.addAll(populateSpeedOverGround(vessel))
244 319
data.add(Pair("Course Over Ground", populateCourseOverGround(vessel))) 245 320 courseOverGround.clear()
321 courseOverGround.addAll(populateCourseOverGround(vessel))
246 322
data.add(Pair("Heading", populateHeading(vessel))) 247 323 heading.clear()
324 heading.addAll(populateHeading(vessel))
248 325
data.add(Pair("Vessel Name", populateVesselName(vessel))) 249 326 vesselName.clear()
327 vesselName.addAll(populateVesselName(vessel))
250 328
data.add(Pair("IMO", populateIMO(vessel))) 251 329 imo.clear()
330 imo.addAll(populateIMO(vessel))
252 331
data.add(Pair("Call Sign", populateCallSign(vessel))) 253 332 callSign.clear()
333 callSign.addAll(populateCallSign(vessel))
254 334
data.add(Pair("Vessel Type", populateVesselType(vessel))) 255 335 vesselType.clear()
336 vesselType.addAll(populateVesselType(vessel))
256 337
data.add(Pair("Status", populateStatus(vessel))) 257 338 status.clear()
339 status.addAll(populateStatus(vessel))
258 340
data.add(Pair("Length", populateLength(vessel))) 259 341 length.clear()
342 length.addAll(populateLength(vessel))
260 343
data.add(Pair("Width", populateWidth(vessel))) 261 344 width.clear()
345 width.addAll(populateWidth(vessel))
262 346
data.add(Pair("Draft", populateDraft(vessel))) 263 347 draft.clear()
348 draft.addAll(populateDraft(vessel))
264 349
data.add(Pair("Cargo", populateCargo(vessel))) 265 350 cargo.clear()
351 cargo.addAll(populateCargo(vessel))
266 352
dataList.addAll(data) 267
} 268 353 }
269 354
override fun onValueChanged(newValue: Vessel) { 270 355 private fun setObservableCurrentTimeListener() {
dataList.clear() 271 356 observableCurrentTime.listeners.add(object : CurrentTime {
populateDataList(newValue) 272 357 override fun onValueChanged(newValue: Int) {
358 updateDataList(observableSelectedVessel.value)
359 plot()
360 }
361 })
362 }
273 363
364 override fun onValueChanged(newValue: Vessel) {
365 updateDataList(newValue)
366 plot()
} 274 367 }
275 368
} 276 369 }
277 370
278 371
279 372
src/main/kotlin/application/controller/MapPanelController.kt View file @ e220e08
package application.controller 1 1 package application.controller
2 2
import application.model.* 3 3 import application.model.*
import application.model.MapState.* 4 4 import application.model.MapState.*
5 import javafx.application.Platform
import javafx.fxml.FXML 5 6 import javafx.fxml.FXML
import javafx.fxml.Initializable 6 7 import javafx.fxml.Initializable
import javafx.scene.layout.StackPane 7 8 import javafx.scene.layout.StackPane
import map.* 8 9 import map.*
import java.net.URL 9 10 import java.net.URL
import java.util.* 10 11 import java.util.*
11 12
class MapPanelController : Initializable { 12 13 class MapPanelController : Initializable {
13 14
@FXML 14 15 @FXML
private lateinit var map: StackPane 15 16 private lateinit var map: StackPane
16 17
private val mapView = LeafletMapView() 17 18 private val mapView = LeafletMapView()
18 19
override fun initialize(location: URL?, resources: ResourceBundle?) { 19 20 override fun initialize(location: URL?, resources: ResourceBundle?) {
mapView.displayMap(MapConfig()) 20 21 mapView.displayMap(MapConfig())
setObservableVesselListener() 21 22 setObservableVesselListener()
setObservableSelectedVesselListener() 22 23 setObservableSelectedVesselListener()
setStateListener() 23 24 setStateListener()
setObservableIsReplayState() 24 25 setObservableIsReplayState()
observableCurrentTime() 25 26 observableCurrentTime()
26 27
map.children.add(mapView) 27 28 map.children.add(mapView)
map.children 28 29 map.children
} 29 30 }
30 31
private fun setStateListener() { 31 32 private fun setStateListener() {
observableMapState.listeners.add(object : StateListener { 32 33 observableMapState.listeners.add(object : StateListener {
override fun onValueChanged(newValue: MapState) { 33 34 override fun onValueChanged(newValue: MapState) {
if (observableSelectedVessel.value.mmsi != null) { 34 35 if (observableSelectedVessel.value.mmsi != null) {
updateMap(observableSelectedVessel.value.mmsi!!) 35 36 updateMap(observableSelectedVessel.value.mmsi!!)
} else { 36 37 } else {
updateMap() 37 38 updateMap()
} 38 39 }
} 39 40 }
}) 40 41 })
} 41 42 }
42 43
private fun observableCurrentTime() { 43 44 private fun observableCurrentTime() {
observableCurrentTime.listeners.add(object : CurrentTime { 44 45 observableCurrentTime.listeners.add(object : CurrentTime {
override fun onValueChanged(newValue: Int) { 45 46 override fun onValueChanged(newValue: Int) {
if (observableSelectedVessel.value.mmsi != null) { 46 47 if (observableSelectedVessel.value.mmsi != null) {
updateMap(observableSelectedVessel.value.mmsi!!) 47 48 updateMap(observableSelectedVessel.value.mmsi!!)
} else { 48 49 } else {
updateMap() 49 50 updateMap()
} 50 51 }
} 51 52 }
}) 52 53 })
} 53 54 }
54 55
private fun updateMap() { 55 56 private fun updateMap() {
if (observableIsReplayState.value) { 56 57 Platform.runLater {
when (observableMapState.state) { 57 58 if (observableIsReplayState.value) {
ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView) 58 59 when (observableMapState.state) {
CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView) 59 60 ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView)
HEAT_MAP -> displayTimedHeatMapOnMap(mapView) 60 61 CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView)
62 HEAT_MAP -> displayTimedHeatMapOnMap(mapView)
63 }
64 } else {
65 when (observableMapState.state) {
66 ALL_MESSAGES -> displayAllMessageOnMap(mapView)
67 CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView)
68 HEAT_MAP -> displayHeatMapOnMap(mapView)
69 }
} 61 70 }
} else { 62
when (observableMapState.state) { 63
ALL_MESSAGES -> displayAllMessageOnMap(mapView) 64
CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView) 65
HEAT_MAP -> displayHeatMapOnMap(mapView) 66
} 67
} 68 71 }
} 69 72 }
70 73
private fun updateMap(selectedMMSI: String) { 71 74 private fun updateMap(selectedMMSI: String) {
if (observableIsReplayState.value) { 72 75 Platform.runLater {
when (observableMapState.state) { 73 76 if (observableIsReplayState.value) {
ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView, selectedMMSI) 74 77 when (observableMapState.state) {
CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView, selectedMMSI) 75 78 ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView, selectedMMSI)
HEAT_MAP -> displayTimedHeatMapOnMap(mapView, selectedMMSI) 76 79 CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView, selectedMMSI)
80 HEAT_MAP -> displayTimedHeatMapOnMap(mapView, selectedMMSI)
81 }
82 } else {
83 when (observableMapState.state) {
84 ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI)
85 CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI)
86 HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI)
87 }
} 77 88 }
} else { 78
when (observableMapState.state) { 79
ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI) 80
CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI) 81
HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI) 82
} 83
} 84 89 }
} 85 90 }
86 91
private fun setObservableVesselListener() { 87 92 private fun setObservableVesselListener() {
observableVessel.listeners.add(object : MessageListener { 88 93 observableVessel.listeners.add(object : MessageListener {
override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { 89 94 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
updateMap() 90 95 updateMap()
} 91 96 }
}) 92 97 })
} 93 98 }
94 99
private fun setObservableIsReplayState() { 95 100 private fun setObservableIsReplayState() {
observableIsReplayState.listeners.add(object: ReplayState { 96 101 observableIsReplayState.listeners.add(object : ReplayState {
override fun onValueChanged(newValue: Boolean) { 97 102 override fun onValueChanged(newValue: Boolean) {
if (observableSelectedVessel.value.mmsi != null) { 98 103 if (observableSelectedVessel.value.mmsi != null) {
updateMap(observableSelectedVessel.value.mmsi!!) 99 104 updateMap(observableSelectedVessel.value.mmsi!!)
} else { 100 105 } else {
updateMap() 101 106 updateMap()
} 102 107 }
} 103 108 }
}) 104 109 })
} 105 110 }
106 111
private fun setObservableSelectedVesselListener() { 107 112 private fun setObservableSelectedVesselListener() {
observableSelectedVessel.listeners.add(object : SelectedVesselListener { 108 113 observableSelectedVessel.listeners.add(object : SelectedVesselListener {
override fun onValueChanged(newValue: Vessel) { 109 114 override fun onValueChanged(newValue: Vessel) {
if (newValue.mmsi != null) { 110 115 if (newValue.mmsi != null) {
updateMap(newValue.mmsi) 111 116 updateMap(newValue.mmsi)
} else { 112 117 } else {
updateMap() 113 118 updateMap()
} 114 119 }
} 115 120 }
}) 116 121 })
src/main/kotlin/application/controller/TimePanel.kt View file @ e220e08
package application.controller 1 1 package application.controller
2 2
import application.model.* 3 3 import application.model.*
import javafx.fxml.FXML 4 4 import javafx.fxml.FXML
import javafx.fxml.Initializable 5 5 import javafx.fxml.Initializable
import javafx.scene.control.Button 6 6 import javafx.scene.control.Button
import javafx.scene.control.Slider 7 7 import javafx.scene.control.Slider
import java.net.URL 8 8 import java.net.URL
import java.util.* 9 9 import java.util.*
10 10
11 11
class TimePanel : Initializable { 12 12 class TimePanel : Initializable {
13 13
@FXML 14 14 @FXML
var timeSlider = Slider() 15 15 var timeSlider = Slider()
16 16
@FXML 17 17 @FXML
var timeStop = Button() 18 18 var timeStop = Button()
19 19
@FXML 20 20 @FXML
var timePlay = Button() 21 21 var timePlay = Button()
22 22
23 23
override fun initialize(location: URL?, resources: ResourceBundle?) { 24 24 override fun initialize(location: URL?, resources: ResourceBundle?) {
setSliderMinMax() 25 25 setSliderMinMax()
setSliderListener() 26 26 setSliderListener()
disableAllButton() 27 27 disableAllButton()
setDisable() 28 28 setDisable()
} 29 29 }
30 30
private fun setSliderMinMax() { 31 31 private fun setSliderMinMax() {
timeSlider.min = 0.0 32 32 timeSlider.min = 0.0
timeSlider.max = 0.0 33 33 timeSlider.max = 0.0
observableVessel.listeners.add(object : MessageListener { 34 34 observableVessel.listeners.add(object : MessageListener {
override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { 35 35 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
timeSlider.max = Vessel.maxTime.toDouble() 36 36 timeSlider.max = Vessel.maxTime.toDouble()
timeSlider.min = Vessel.minTime.toDouble() 37 37 timeSlider.min = Vessel.minTime.toDouble()
} 38 38 }
}) 39 39 })
} 40 40 }
41 41
private fun setSliderListener() { 42 42 private fun setSliderListener() {
timeSlider.valueProperty().addListener { _, _, newValue -> 43 43 timeSlider.valueProperty().addListener { _, _, newValue ->
observableCurrentTime.value = newValue.toInt() 44 44 observableCurrentTime.value = newValue.toInt()
} 45 45 }
} 46 46 }
47 47
private fun disableAllButton() { 48 48 private fun disableAllButton() {
timeStop.isDisable = true 49 49 timeStop.isDisable = true
timeSlider.isDisable = true 50 50 timeSlider.isDisable = true
timePlay.isDisable = true 51 51 timePlay.isDisable = true
} 52 52 }
53 53
private fun unableAllButton() { 54 54 private fun unableAllButton() {
timeStop.isDisable = false 55 55 timeStop.isDisable = false
timeSlider.isDisable = false 56 56 timeSlider.isDisable = false
timePlay.isDisable = false 57 57 timePlay.isDisable = false
} 58 58 }
59 59
private fun setDisable() { 60 60 private fun setDisable() {
src/main/kotlin/application/model/ObservableCurrentTime.kt View file @ e220e08
package application.model 1 1 package application.model
2 2
import kotlin.properties.Delegates 3 3 import kotlin.properties.Delegates
4 4
class ObservableCurrentTime { 5 5 class ObservableCurrentTime {
6 6
val listeners: MutableList<CurrentTime> = mutableListOf() 7 7 val listeners: MutableList<CurrentTime> = mutableListOf()
8 8
var value: Int by Delegates.observable( 9 9 var value: Int by Delegates.observable(
initialValue = 0, 10 10 initialValue = Int.MAX_VALUE,
onChange = { _, _, new -> 11 11 onChange = { _, _, new ->
run { 12 12 run {
listeners.forEach { 13 13 listeners.forEach {
it.onValueChanged(new) 14 14 it.onValueChanged(new)
} 15 15 }
} 16 16 }
src/main/kotlin/application/model/Vessel.kt View file @ e220e08
package application.model 1 1 package application.model
2 2
import java.util.* 3 3 import java.util.*
4 4
5
class Vessel(val mmsi: String?) { 6 5 class Vessel(val mmsi: String?) {
val messages: SortedMap<Long, Message> = sortedMapOf() 7 6 val messages: SortedMap<Long, Message> = sortedMapOf()
7 private val messageBeforeSelectedTime: Map<Long, Message>
8 get() {
9 return messages.filter { observableCurrentTime.value > it.key }
10 }
11
var messageToDisplay: Message? = null 8 12 var messageToDisplay: Message? = null
get() { 9 13 get() {
field = 10 14 field =
messages.asSequence().map { it }.firstOrNull { observableCurrentTime.value < it.key }.let { it?.value } 11 15 messages.asSequence().map { it }.firstOrNull { observableCurrentTime.value < it.key }.let { it?.value }
return field 12 16 return field
} 13 17 }
18
19 fun getAllTimeBeforeSelectedTime(): ArrayList<MessageData?> {
20 val timeList = arrayListOf<MessageData?>()
21 messageBeforeSelectedTime.forEach {
22 timeList.add(it.value.time)
23 }
24
25 return timeList
26 }
27
28 fun getAllLatitudeBeforeSelectedTime(): ArrayList<MessageData?> {
29 val latitudeList = arrayListOf<MessageData?>()
30 messageBeforeSelectedTime.forEach {
31 latitudeList.add(it.value.latitude)
32 }
33
34 return latitudeList
35 }
36
37 fun getAllLongitudeBeforeSelectedTime(): ArrayList<MessageData?> {
38 val longitudeList = arrayListOf<MessageData?>()
39 messageBeforeSelectedTime.forEach {
40 longitudeList.add(it.value.longitude)
41 }
42
43 return longitudeList
44 }
45
46 fun getAllSpeedOverGroundBeforeSelectedTime(): ArrayList<MessageData?> {
47 val speedOverGroundList = arrayListOf<MessageData?>()
48 messageBeforeSelectedTime.forEach {
49 speedOverGroundList.add(it.value.speedOverGround)
50 }
51
52 return speedOverGroundList
53 }
54
55 fun getAllCourseOverGroundBeforeSelectedTime(): ArrayList<MessageData?> {
56 val res = arrayListOf<MessageData?>()
57 messageBeforeSelectedTime.forEach {
58 res.add(it.value.courseOverGround)
59 }
60
61 return res
62 }
63
64 fun getAllHeadingBeforeSelectedTime(): ArrayList<MessageData?> {
65 val res = arrayListOf<MessageData?>()
66 messageBeforeSelectedTime.forEach {
67 res.add(it.value.heading)
68 }
69
70 return res
71 }
72
73 fun getAllVesselNameBeforeSelectedTime(): ArrayList<MessageData?> {
74 val res = arrayListOf<MessageData?>()
75 messageBeforeSelectedTime.forEach {
76 res.add(it.value.vesselName)
77 }
78 return res
79 }
80
81 fun getAllIMOBeforeSelectedTime(): ArrayList<MessageData?> {
82 val res = arrayListOf<MessageData?>()
83 messageBeforeSelectedTime.forEach {
84 res.add(it.value.imo)
85 }
86 return res
87 }
88
89 fun getAllCallSignBeforeSelectedTime(): ArrayList<MessageData?> {
90 val res = arrayListOf<MessageData?>()
91 messageBeforeSelectedTime.forEach {
92 res.add(it.value.callSign)
93 }
94 return res
95 }
96
97 fun getAllVesselTypeBeforeSelectedTime(): ArrayList<MessageData?> {
98 val res = arrayListOf<MessageData?>()
99 messageBeforeSelectedTime.forEach {
100 res.add(it.value.vesselType)
101 }
102 return res
103 }
104
105 fun getAllStatusBeforeSelectedTime(): ArrayList<MessageData?> {
106 val res = arrayListOf<MessageData?>()
107 messageBeforeSelectedTime.forEach {
108 res.add(it.value.status)
109 }
110 return res
111 }
112
113 fun getAllLengthBeforeSelectedTime(): ArrayList<MessageData?> {
114 val res = arrayListOf<MessageData?>()
115 messageBeforeSelectedTime.forEach {
116 res.add(it.value.length)
117 }
118 return res
119 }
120
121 fun getAllWidthBeforeSelectedTime(): ArrayList<MessageData?> {
122 val res = arrayListOf<MessageData?>()
123 messageBeforeSelectedTime.forEach {
124 res.add(it.value.width)
125 }
126 return res
127 }
128
129 fun getAllDraftBeforeSelectedTime(): ArrayList<MessageData?> {
130 val res = arrayListOf<MessageData?>()
131 messageBeforeSelectedTime.forEach {
132 res.add(it.value.draft)
133 }
134 return res
135 }
136
137 fun getAllCargoBeforeSelectedTime(): ArrayList<MessageData?> {
138 val res = arrayListOf<MessageData?>()
139 messageBeforeSelectedTime.forEach {
140 res.add(it.value.cargo)
141 }
142 return res
143 }
14 144
fun getAllTime(): ArrayList<MessageData?> { 15 145 fun getAllTime(): ArrayList<MessageData?> {
val timeList = arrayListOf<MessageData?>() 16 146 val timeList = arrayListOf<MessageData?>()
messages.forEach { 17 147 messages.forEach {
timeList.add(it.value.time) 18 148 timeList.add(it.value.time)
} 19 149 }
20 150
return timeList 21 151 return timeList
} 22 152 }
23 153
fun getAllLatitude(): ArrayList<MessageData?> { 24 154 fun getAllLatitude(): ArrayList<MessageData?> {
val latitudeList = arrayListOf<MessageData?>() 25 155 val latitudeList = arrayListOf<MessageData?>()
messages.forEach { 26 156 messages.forEach {
latitudeList.add(it.value.latitude) 27 157 latitudeList.add(it.value.latitude)
} 28 158 }
29 159
return latitudeList 30 160 return latitudeList
} 31 161 }
32 162
fun getAllLongitude(): ArrayList<MessageData?> { 33 163 fun getAllLongitude(): ArrayList<MessageData?> {
val longitudeList = arrayListOf<MessageData?>() 34 164 val longitudeList = arrayListOf<MessageData?>()
messages.forEach { 35 165 messages.forEach {
longitudeList.add(it.value.longitude) 36 166 longitudeList.add(it.value.longitude)
} 37 167 }
38 168
return longitudeList 39 169 return longitudeList
} 40 170 }
41 171
fun getAllSpeedOverGround(): ArrayList<MessageData?> { 42 172 fun getAllSpeedOverGround(): ArrayList<MessageData?> {
val speedOverGroundList = arrayListOf<MessageData?>() 43 173 val speedOverGroundList = arrayListOf<MessageData?>()
messages.forEach { 44 174 messages.forEach {
speedOverGroundList.add(it.value.speedOverGround) 45 175 speedOverGroundList.add(it.value.speedOverGround)
} 46 176 }
47 177
return speedOverGroundList 48 178 return speedOverGroundList
} 49 179 }
50 180
fun getAllCourseOverGround(): ArrayList<MessageData?> { 51 181 fun getAllCourseOverGround(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 52 182 val res = arrayListOf<MessageData?>()
messages.forEach { 53 183 messages.forEach {
res.add(it.value.courseOverGround) 54 184 res.add(it.value.courseOverGround)
} 55 185 }
56 186
return res 57 187 return res
} 58 188 }
59 189
fun getAllHeading(): ArrayList<MessageData?> { 60 190 fun getAllHeading(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 61 191 val res = arrayListOf<MessageData?>()
messages.forEach { 62 192 messages.forEach {
res.add(it.value.heading) 63 193 res.add(it.value.heading)
} 64 194 }
65 195
return res 66 196 return res
} 67 197 }
68 198
fun getAllVesselName(): ArrayList<MessageData?> { 69 199 fun getAllVesselName(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 70 200 val res = arrayListOf<MessageData?>()
messages.forEach { 71 201 messages.forEach {
res.add(it.value.vesselName) 72 202 res.add(it.value.vesselName)
} 73 203 }
return res 74 204 return res
} 75 205 }
76 206
fun getAllIMO(): ArrayList<MessageData?> { 77 207 fun getAllIMO(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 78 208 val res = arrayListOf<MessageData?>()
messages.forEach { 79 209 messages.forEach {
res.add(it.value.imo) 80 210 res.add(it.value.imo)
} 81 211 }
return res 82 212 return res
} 83 213 }
84 214
fun getAllCallSign(): ArrayList<MessageData?> { 85 215 fun getAllCallSign(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 86 216 val res = arrayListOf<MessageData?>()
messages.forEach { 87 217 messages.forEach {
res.add(it.value.callSign) 88 218 res.add(it.value.callSign)
} 89 219 }
return res 90 220 return res
} 91 221 }
92 222
fun getAllVesselType(): ArrayList<MessageData?> { 93 223 fun getAllVesselType(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 94 224 val res = arrayListOf<MessageData?>()
messages.forEach { 95 225 messages.forEach {
res.add(it.value.vesselType) 96 226 res.add(it.value.vesselType)
} 97 227 }
return res 98 228 return res
} 99 229 }
100 230
fun getAllStatus(): ArrayList<MessageData?> { 101 231 fun getAllStatus(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 102 232 val res = arrayListOf<MessageData?>()
messages.forEach { 103 233 messages.forEach {
res.add(it.value.status) 104 234 res.add(it.value.status)
} 105 235 }
return res 106 236 return res
} 107 237 }
108 238
fun getAllLength(): ArrayList<MessageData?> { 109 239 fun getAllLength(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 110 240 val res = arrayListOf<MessageData?>()
messages.forEach { 111 241 messages.forEach {
res.add(it.value.length) 112 242 res.add(it.value.length)
} 113 243 }
return res 114 244 return res
} 115 245 }
116 246
fun getAllWidth(): ArrayList<MessageData?> { 117 247 fun getAllWidth(): ArrayList<MessageData?> {
val res = arrayListOf<MessageData?>() 118 248 val res = arrayListOf<MessageData?>()
messages.forEach { 119 249 messages.forEach {
res.add(it.value.width) 120 250 res.add(it.value.width)
src/main/resources/gui/timePanel.fxml View file @ e220e08
<?xml version="1.0" encoding="UTF-8"?> 1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2
<?import javafx.geometry.*?> 3 3 <?import javafx.geometry.*?>
<?import javafx.scene.control.*?> 4 4 <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> 5 5 <?import javafx.scene.layout.*?>
6 6
<HBox alignment="CENTER" prefHeight="65.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.TimePanel"> 7 7 <HBox alignment="CENTER" prefHeight="65.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.TimePanel">
<children> 8 8 <children>
<Button fx:id="timePlay" alignment="CENTER" mnemonicParsing="false" text="Play"> 9 9 <Slider fx:id="timeSlider" prefHeight="14.0" prefWidth="538.0">
<HBox.margin> 10
<Insets left="5.0" right="5.0" /> 11
</HBox.margin></Button> 12
<Button fx:id="timeStop" mnemonicParsing="false" text="Stop"> 13
<HBox.margin> 14
<Insets left="5.0" right="5.0" /> 15
</HBox.margin></Button> 16
<Slider fx:id="timeSlider" prefHeight="14.0" prefWidth="475.0"> 17
<HBox.margin> 18 10 <HBox.margin>
<Insets left="5.0" right="5.0" /> 19 11 <Insets left="5.0" right="5.0" />
</HBox.margin></Slider> 20 12 </HBox.margin></Slider>
</children> 21 13 </children>