diff --git a/.gitignore b/.gitignore
index 5ca5dcda..1d2cb5bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,3 +71,31 @@ settings.xml
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location
.metadata/.lock
+.metadata/version.ini
+.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
+.metadata/.plugins/org.eclipse.ui.intro/introstate
+.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml
+.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup
+.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml
+.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
+.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
+.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
+.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
+.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
+.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
+.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
+.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
+.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache
+.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs
+.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
+.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
+.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
+.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
+.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
+.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
+.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
diff --git a/.metadata/.lock b/.metadata/.lock
new file mode 100644
index 00000000..e69de29b
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location
new file mode 100644
index 00000000..98851383
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
new file mode 100644
index 00000000..25cb955b
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
new file mode 100644
index 00000000..d2372511
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
new file mode 100644
index 00000000..6b2aaa76
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
new file mode 100644
index 00000000..89bbc184
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree differ
diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
new file mode 100644
index 00000000..bd315dac
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..30841ebf
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding=UTF-8
+version=1
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000..67094041
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.formatterprofiles.version=23
+spelling_locale=en_GB
+spelling_locale_initialized=true
+typefilter_migrated_2=true
+useAnnotationsPrefPage=true
+useQuickDiffPrefPage=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
new file mode 100644
index 00000000..67b1d96c
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.m2e.discovery.pref.projects=
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
new file mode 100644
index 00000000..bc1720e5
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+platformState=1678968029917
+quickStart=false
+tipsAndTricks=true
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
new file mode 100644
index 00000000..08076f23
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+showIntro=false
diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
new file mode 100644
index 00000000..7e380fb0
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
@@ -0,0 +1,12 @@
+//org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false
+PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery;
+eclipse.preferences.version=1
+org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_END=41,41,41
+org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_START=43,44,45
+org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_TEXT_COLOR=204,204,204
+org.eclipse.ui.workbench.ACTIVE_TAB_BG_END=41,41,41
+org.eclipse.ui.workbench.ACTIVE_TAB_BG_START=43,44,45
+org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR=221,221,221
+org.eclipse.ui.workbench.INACTIVE_TAB_BG_END=49,53,56
+org.eclipse.ui.workbench.INACTIVE_TAB_BG_START=59,64,66
+org.eclipse.ui.workbench.INACTIVE_TAB_TEXT_COLOR=187,187,187
diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
new file mode 100644
index 00000000..8106a865
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
@@ -0,0 +1,2360 @@
+
+
+
+ activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration
+
+
+
+
+
+
+
+ topLevel
+
+
+
+
+ persp.actionSet:org.eclipse.ui.cheatsheets.actionSet
+ persp.actionSet:org.eclipse.search.searchActionSet
+ persp.actionSet:org.eclipse.text.quicksearch.actionSet
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation
+ persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo
+ persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet
+ persp.actionSet:org.eclipse.ui.actionSet.keyBindings
+ persp.actionSet:org.eclipse.ui.actionSet.openFiles
+ persp.actionSet:org.eclipse.debug.ui.launchActionSet
+ persp.actionSet:org.eclipse.jdt.ui.JavaActionSet
+ persp.actionSet:org.eclipse.jdt.ui.JavaElementCreationActionSet
+ persp.actionSet:org.eclipse.ui.NavigateActionSet
+ persp.viewSC:org.eclipse.jdt.ui.PackageExplorer
+ persp.viewSC:org.eclipse.jdt.ui.TypeHierarchy
+ persp.viewSC:org.eclipse.jdt.ui.SourceView
+ persp.viewSC:org.eclipse.jdt.ui.JavadocView
+ persp.viewSC:org.eclipse.search.ui.views.SearchView
+ persp.viewSC:org.eclipse.ui.console.ConsoleView
+ persp.viewSC:org.eclipse.ui.views.ContentOutline
+ persp.viewSC:org.eclipse.ui.views.ProblemView
+ persp.viewSC:org.eclipse.ui.views.TaskList
+ persp.viewSC:org.eclipse.ui.views.ProgressView
+ persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer
+ persp.viewSC:org.eclipse.ui.texteditor.TemplatesView
+ persp.viewSC:org.eclipse.pde.runtime.LogView
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.JavaProjectWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewPackageCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewClassCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewEnumCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewRecordCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard
+ persp.newWizSC:org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard
+ persp.newWizSC:org.eclipse.ui.wizards.new.folder
+ persp.newWizSC:org.eclipse.ui.wizards.new.file
+ persp.newWizSC:org.eclipse.ui.editors.wizards.UntitledTextFileWizard
+ persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective
+ persp.perspSC:org.eclipse.debug.ui.DebugPerspective
+ persp.showIn:org.eclipse.jdt.ui.PackageExplorer
+ persp.showIn:org.eclipse.team.ui.GenericHistoryView
+ persp.showIn:org.eclipse.ui.navigator.ProjectExplorer
+ persp.actionSet:org.eclipse.debug.ui.breakpointActionSet
+ persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet
+ persp.showIn:org.eclipse.egit.ui.RepositoriesView
+ persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard
+ persp.actionSet:org.eclipse.eclemma.ui.CoverageActionSet
+ persp.showIn:org.eclipse.eclemma.ui.CoverageView
+ persp.viewSC:org.eclipse.tm.terminal.view.ui.TerminalsView
+ persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView
+ persp.viewSC:org.eclipse.jdt.bcoview.views.BytecodeOutlineView
+ persp.newWizSC:org.eclipse.jdt.junit.wizards.NewTestCaseCreationWizard
+ persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet
+ persp.viewSC:org.eclipse.ant.ui.views.AntView
+
+
+
+ org.eclipse.e4.primaryNavigationStack
+ active
+ noFocus
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+
+
+
+ org.eclipse.e4.secondaryNavigationStack
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Ant
+
+
+
+
+ org.eclipse.e4.secondaryDataStack
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:Java
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Terminal
+
+
+
+
+
+
+
+
+ View
+ categoryTag:Help
+
+
+ View
+ categoryTag:General
+
+
+ View
+ categoryTag:Help
+
+
+
+
+
+
+ View
+ categoryTag:Help
+
+
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+
+ View
+ categoryTag:Help
+
+
+
+ org.eclipse.e4.primaryDataStack
+ EditorStack
+
+
+
+
+
+
+ View
+ categoryTag:Java
+ active
+ activeOnClose
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+
+ View
+ categoryTag:General
+
+ ViewMenu
+ menuContribution:menu
+
+
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+ View
+ categoryTag:Terminal
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Ant
+
+
+
+ toolbarSeparator
+
+
+
+ Draggable
+
+
+
+ toolbarSeparator
+
+
+
+ Draggable
+
+
+ toolbarSeparator
+
+
+
+ Draggable
+
+
+ Draggable
+
+
+ Draggable
+
+
+ toolbarSeparator
+
+
+
+ Draggable
+
+
+
+ toolbarSeparator
+
+
+
+ toolbarSeparator
+
+
+
+ Draggable
+
+
+ stretch
+ SHOW_RESTORE_MENU
+
+
+ Draggable
+ HIDEABLE
+ SHOW_RESTORE_MENU
+
+
+
+
+ stretch
+
+
+ Draggable
+
+
+ Draggable
+
+
+
+
+ TrimStack
+ Draggable
+
+
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+ platform:cocoa
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+ platform:cocoa
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ platform:cocoa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Editor
+ removeOnHide
+
+
+
+
+ View
+ categoryTag:Ant
+
+
+
+
+ View
+ categoryTag:Gradle
+
+
+
+
+ View
+ categoryTag:Gradle
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+ View
+ categoryTag:Git
+ NoRestore
+
+
+
+
+ View
+ categoryTag:Git
+
+
+
+
+ View
+ categoryTag:Help
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Debug
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java Browsing
+
+
+
+
+ View
+ categoryTag:Java Browsing
+
+
+
+
+ View
+ categoryTag:Java Browsing
+
+
+
+
+ View
+ categoryTag:Java Browsing
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Java
+
+
+
+
+ View
+ categoryTag:Maven
+
+
+
+
+ View
+ categoryTag:Maven
+
+
+
+
+ View
+ categoryTag:Maven
+
+
+
+
+ View
+ categoryTag:Oomph
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:Version Control (Team)
+
+
+
+
+ View
+ categoryTag:Version Control (Team)
+
+
+ View
+ categoryTag:Help
+
+
+
+
+ View
+ categoryTag:Terminal
+
+
+
+
+ View
+ categoryTag:Other
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:Help
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+
+ View
+ categoryTag:General
+
+
+
+ glue
+ move_after:PerspectiveSpacer
+ SHOW_RESTORE_MENU
+
+
+ move_after:Spacer Glue
+ HIDEABLE
+ SHOW_RESTORE_MENU
+
+
+ glue
+ move_after:SearchField
+ SHOW_RESTORE_MENU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000..99f26c02
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache
new file mode 100644
index 00000000..593f4708
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
new file mode 100644
index 00000000..593f4708
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
new file mode 100644
index 00000000..85863977
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
@@ -0,0 +1 @@
+java
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
new file mode 100644
index 00000000..593f4708
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
new file mode 100644
index 00000000..0edae4b2
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
new file mode 100644
index 00000000..a4ee3cbc
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
new file mode 100644
index 00000000..9e390f50
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
new file mode 100644
index 00000000..c8468c1f
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser b/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
new file mode 100644
index 00000000..abbf8e52
Binary files /dev/null and b/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser differ
diff --git a/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml b/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml
new file mode 100644
index 00000000..abdf1c73
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml
@@ -0,0 +1,41 @@
+
+
+
+ %date [%thread] %-5level %logger{35} - %msg%n
+
+
+ OFF
+
+
+
+
+ ${org.eclipse.m2e.log.dir}/0.log
+
+ ${org.eclipse.m2e.log.dir}/%i.log
+ 1
+ 10
+
+
+ 10MB
+
+
+ %date [%thread] %-5level %logger{35} - %msg%n
+
+
+
+
+
+ WARN
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup b/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup
new file mode 100644
index 00000000..1f73e14c
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup
@@ -0,0 +1,6 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml
new file mode 100644
index 00000000..5ca0b776
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/.metadata/.plugins/org.eclipse.ui.intro/introstate b/.metadata/.plugins/org.eclipse.ui.intro/introstate
new file mode 100644
index 00000000..02f134f0
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.intro/introstate
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
new file mode 100644
index 00000000..cc5a0219
--- /dev/null
+++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.metadata/version.ini b/.metadata/version.ini
new file mode 100644
index 00000000..c005b7a5
--- /dev/null
+++ b/.metadata/version.ini
@@ -0,0 +1,3 @@
+#Thu Mar 16 12:01:36 GMT 2023
+org.eclipse.core.runtime=2
+org.eclipse.platform=4.27.0.v20230302-0300
diff --git a/pom.xml b/pom.xml
index 6f403717..b4c82050 100644
--- a/pom.xml
+++ b/pom.xml
@@ -842,7 +842,6 @@ C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2-->
atlantafx-base
1.0.0
-
-
+
\ No newline at end of file
diff --git a/src/Array/Streamer.java b/src/Array/Streamer.java
index 81c34a64..ccdb70c1 100644
--- a/src/Array/Streamer.java
+++ b/src/Array/Streamer.java
@@ -666,8 +666,8 @@ public class Streamer implements Serializable, Cloneable, ManagedParameters {
*/
@Override
public String toString() {
- return super.toString() + "; OriginSettings: " + getOriginSettings().toString() + "," + getHydrophoneOrigin().getOriginSettings().toString() +
- "; Locator " + getLocatorSettings().toString();
+ return super.toString() + "; OriginSettings: " + getOriginSettings()==null ? "null" : getOriginSettings().toString() + "," + getHydrophoneOrigin().getOriginSettings().toString() +
+ "; Locator " + getLocatorSettings()==null ? "null" : getLocatorSettings().toString();
}
public static Streamer getAverage(Streamer sd1,
diff --git a/src/Array/StreamerDialog.java b/src/Array/StreamerDialog.java
index e629b142..bb07b65b 100644
--- a/src/Array/StreamerDialog.java
+++ b/src/Array/StreamerDialog.java
@@ -317,7 +317,7 @@ public class StreamerDialog extends PamDialog {
PamDialog.setDoubleValue(heading, defaultStreamer.getHeading(), "%3.1f");
PamDialog.setDoubleValue(pitch, defaultStreamer.getPitch(), "%3.1f");
PamDialog.setDoubleValue(roll, defaultStreamer.getRoll(), "%3.1f");
-
+
interpolationPanel.setSelection(currentArray.getOriginInterpolation());
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
@@ -375,6 +375,9 @@ public class StreamerDialog extends PamDialog {
defaultStreamer.setStreamerName(streamerName.getText());
int im = interpolationPanel.getSelection();
+
+ System.out.println("GetParams: INTERPOLATION SELECTION: " + currentArray.getOriginInterpolation());
+
if (im < 0) {
return showWarning("Invalid interpolation selection");
}
diff --git a/src/Array/layoutFX/Array3DPane.java b/src/Array/layoutFX/Array3DPane.java
new file mode 100644
index 00000000..25100563
--- /dev/null
+++ b/src/Array/layoutFX/Array3DPane.java
@@ -0,0 +1,383 @@
+package Array.layoutFX;
+
+import pamViewFX.fxNodes.PamBorderPane;
+
+
+import java.util.ArrayList;
+
+import javafx.event.EventHandler;
+import javafx.scene.AmbientLight;
+import javafx.scene.DepthTest;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.SceneAntialiasing;
+import javafx.scene.SubScene;
+import javafx.scene.control.Label;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.ScrollEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.Box;
+import javafx.geometry.Point3D;
+
+import javafx.scene.shape.Sphere;
+import javafx.scene.text.Text;
+import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Translate;
+
+/**
+ * Create a 3D visualisation of the array.
+ *
+ PAMGUARD co-rdinate system is
+ *
+ * x points right
+ *
+ * y points north or into the screen
+ *
+ * z is height and points up
+ *
+ * This is different from the JavAFX 3D system in which
+ *
+ * x points right
+ *
+ * y points down
+ *
+ * z points into the screen
+ *
+ * Thus the source code for this class is a little bit more complex. By convention the co-ordinate system is only changed for display purposes and remains
+ * in PAMGUARD format throughout the rest of code.
+ * @author Jamie Macaulay
+ *
+ */
+public class Array3DPane extends PamBorderPane {
+
+ public static final Color DEFAULT_HYDRO_COL = Color.RED;
+
+ private static final Color DEFAULT_SENSOR_COL = Color.LIMEGREEN;
+
+
+ private double scaleFactor=20;
+ private double axisSize=10*scaleFactor;
+
+ //keep track of mouse positions
+ double mousePosX;
+ double mousePosY;
+ double mouseOldX;
+ double mouseOldY;
+ double mouseDeltaX;
+ double mouseDeltaY;
+
+ /**
+ * This is the group which rotates
+ */
+ Group root3D;
+
+ /**
+ * Group which holds array shapes.
+ */
+ Group arrayGroup;
+
+ /**
+ * Group which holds axis and other non changing bits.
+ */
+ Group axisGroup;
+
+ /**
+ * The camera transforms
+ */
+ private Rotate rotateY;
+ private Rotate rotateX;
+ private Translate translate;
+
+
+
+ public Array3DPane(){
+
+ // Create and position camera
+ PerspectiveCamera camera = new PerspectiveCamera(true);
+ camera.setFarClip(20000);
+ camera.setNearClip(0.1);
+ camera.setDepthTest(DepthTest.ENABLE);
+ camera.getTransforms().addAll (
+ rotateY=new Rotate(-45, Rotate.Y_AXIS),
+ rotateX=new Rotate(-45, Rotate.X_AXIS),
+ translate=new Translate(0, 200, -2000));
+
+ //create main 3D group
+ root3D=new Group();
+ axisGroup=buildAxes(axisSize); //create axis group
+ arrayGroup=new Group();
+
+ root3D.getChildren().add(arrayGroup);
+ root3D.getChildren().add(axisGroup);
+
+
+ AmbientLight light = new AmbientLight();
+ light.setColor(Color.WHITE);
+ Group lightGroup = new Group();
+ lightGroup.getChildren().add(light);
+ root3D.getChildren().add(lightGroup);
+
+ //Use a SubScene to mix 3D and 2D stuff.
+ //note- make sure depth buffer in sub scene is enabled.
+ SubScene subScene = new SubScene(root3D, 500,400, true, SceneAntialiasing.BALANCED);
+ subScene.widthProperty().bind(this.widthProperty());
+ subScene.heightProperty().bind(this.heightProperty());
+ subScene.setDepthTest(DepthTest.ENABLE);
+
+ //note the fill is actually quite important because if you don't have it mouse rotations etc
+ //onyl work if you select a 3D shape
+ subScene.setFill(Color.TRANSPARENT);
+ subScene.setCamera(camera);
+
+ //handle mouse events for sub scene
+ handleMouse(subScene);
+
+
+
+ //create new group to add sub scene to
+ Group group = new Group();
+ group.getChildren().add(subScene);
+
+ //add group to window.
+ this.setCenter(group);
+ this.setDepthTest(DepthTest.ENABLE);
+
+ }
+
+ /**
+ * Create a 3D axis with default colours set.
+ * @param- size of the axis
+ */
+ public Group buildAxes(double axisSize) {
+ return buildAxes( axisSize,Color.RED, Color.RED,
+ Color.GREEN, Color.GREEN,
+ Color.BLUE, Color.BLUE,
+ Color.WHITE);
+ }
+
+
+ /**
+ * Create a 3D axis.
+ * @param- size of the axis
+ */
+ public static Group buildAxes(double axisSize, Color xAxisDiffuse, Color xAxisSpectacular,
+ Color yAxisDiffuse, Color yAxisSpectacular,
+ Color zAxisDiffuse, Color zAxisSpectacular,
+ Color textColour) {
+
+ Group axisGroup=new Group();
+
+ double length = 2d*axisSize;
+ double width = axisSize/100d;
+ double radius = 2d*axisSize/100d;
+
+
+ final PhongMaterial redMaterial = new PhongMaterial();
+ redMaterial.setDiffuseColor(xAxisDiffuse);
+ redMaterial.setSpecularColor(xAxisSpectacular);
+ final PhongMaterial greenMaterial = new PhongMaterial();
+ greenMaterial.setDiffuseColor(yAxisDiffuse);
+ greenMaterial.setSpecularColor( yAxisSpectacular);
+ final PhongMaterial blueMaterial = new PhongMaterial();
+ blueMaterial.setDiffuseColor(zAxisDiffuse);
+ blueMaterial.setSpecularColor(zAxisSpectacular);
+
+ Text xText=new Text("x");
+ xText.setStyle("-fx-font: 20px Tahoma;");
+ xText.setFill(textColour);
+ xText.setStroke(textColour);
+
+ Text yText=new Text("z");
+ yText.setStyle("-fx-font: 20px Tahoma; ");
+ yText.setFill(textColour);
+ yText.setStroke(textColour);
+
+ Text zText=new Text("y");
+ zText.setStyle("-fx-font: 20px Tahoma; ");
+ zText.setFill(textColour);
+ zText.setStroke(textColour);
+
+ xText.setTranslateX(axisSize+5);
+ xText.setTranslateZ(1); //dunno why but shifting a little in z is required to see colour
+
+ yText.setTranslateY(-(axisSize+5));
+ yText.setTranslateZ(1); //dunno why but shifting a little in z is required to see colour
+
+ zText.setTranslateZ(axisSize+5);
+
+ Sphere xSphere = new Sphere(radius);
+ Sphere ySphere = new Sphere(radius);
+ Sphere zSphere = new Sphere(radius);
+ xSphere.setMaterial(redMaterial);
+ ySphere.setMaterial(greenMaterial);
+ zSphere.setMaterial(blueMaterial);
+
+ xSphere.setTranslateX(axisSize);
+ ySphere.setTranslateY(-axisSize);
+ zSphere.setTranslateZ(axisSize);
+
+ Box xAxis = new Box(length, width, width);
+ Box yAxis = new Box(width, length, width);
+ Box zAxis = new Box(width, width, length);
+ xAxis.setMaterial(redMaterial);
+ yAxis.setMaterial(greenMaterial);
+ zAxis.setMaterial(blueMaterial);
+
+ axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
+ axisGroup.getChildren().addAll(xText, yText, zText);
+ axisGroup.getChildren().addAll(xSphere, ySphere, zSphere);
+
+
+ return axisGroup;
+ }
+
+
+ private void handleMouse(SubScene scene) {
+
+ scene.setOnMousePressed(new EventHandler() {
+
+ @Override public void handle(MouseEvent me) {
+ mousePosX = me.getSceneX();
+ mousePosY = me.getSceneY();
+ mouseOldX = me.getSceneX();
+ mouseOldY = me.getSceneY();
+ }
+ });
+
+ scene.setOnScroll(new EventHandler() {
+ @Override public void handle(ScrollEvent event) {
+ // System.out.println("Scroll Event: "+event.getDeltaX() + " "+event.getDeltaY());
+ translate.setZ(translate.getZ()+ event.getDeltaY() *0.001*translate.getZ()); // +
+ }
+ });
+
+
+ scene.setOnMouseDragged(new EventHandler() {
+
+ @Override
+ public void handle(MouseEvent me) {
+ mouseOldX = mousePosX;
+ mouseOldY = mousePosY;
+ mousePosX = me.getSceneX();
+ mousePosY = me.getSceneY();
+ mouseDeltaX = (mousePosX - mouseOldX);
+ mouseDeltaY = (mousePosY - mouseOldY);
+
+ double modifier = 1.0;
+ double modifierFactor = 0.1;
+
+ if (me.isControlDown()) {
+ modifier = 0.1;
+ }
+ if (me.isShiftDown()) {
+ modifier = 10.0;
+ }
+ if (me.isPrimaryButtonDown()) {
+ rotateY.setAngle(rotateY.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0); // +
+ rotateX.setAngle(rotateX.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0); // -
+ }
+ if (me.isSecondaryButtonDown()) {
+ translate.setX(translate.getX() -mouseDeltaX * modifierFactor * modifier * 5);
+ translate.setY(translate.getY() - mouseDeltaY * modifierFactor * modifier * 5); // +
+ }
+
+
+ }
+ });
+ }
+
+
+
+// /**
+// * Draw the entire array
+// * @param pos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
+// */
+// public void drawArrays(ArrayList> pos){
+//
+// arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
+//
+// if (pos==null){
+// System.err.println("Array3DPane: Hydrophone positions are null");
+// return;
+// }
+//
+// for (int i=0; i< pos.size(); i++){
+// for (int j=0; j streamerPoints;
+//
+// for (int i=0; i();
+// for (int j=0; j{
+ /**
+ * Minimum size of the 3D pane
+ */
+ private static final double MIN_3D_WIDTH = 450;
+
private StreamersPane streamerPane;
- private Pane mainPane;
+ private PamBorderPane mainPane;
private HydrophonesPane hydrophonePane;
// private Pane holder;
- private Label hydrophoneLabel;
+ private Label hydrophoneLabel;
+
+ /**
+ * Pane which shows a 3D representation of the hydrophone array.
+ */
+ private Array3DPane array3DPane;
public ArraySettingsPane() {
super(null);
- mainPane = createArrayPane();
+ mainPane=new PamBorderPane();
+
+ mainPane.setCenter(createArrayPane());
// mainPane.setStyle("-fx-background-color: red;");
mainPane.setMaxWidth(Double.MAX_VALUE);
- mainPane.setPrefWidth(800);
+ mainPane.setMinWidth(1100);
mainPane.setStyle("-fx-padding: 0,0,0,0");
+
+ mainPane.setRight(create3DPane());
+
+ streamerPane.getStreamerTable().getItems().addListener((ListChangeListener super StreamerProperty>) c->{
+ //the streamer table has changed and so the streamer needs changed
+ System.out.println("Streamer Changed!!!");
+ });
+
// mainPane.setMinWidth(800);
@@ -87,6 +109,14 @@ public class ArraySettingsPane extends SettingsPane{
}
+ private Pane create3DPane() {
+ this.array3DPane = new Array3DPane();
+
+ //important because the 3D pane has not default size
+ array3DPane.setMinWidth(MIN_3D_WIDTH);
+ return array3DPane;
+ }
+
/**
* Create the main pane.
* @return the main array pane.
diff --git a/src/Array/layoutFX/HydrophonesPane.java b/src/Array/layoutFX/HydrophonesPane.java
index c7997ffa..2681b720 100644
--- a/src/Array/layoutFX/HydrophonesPane.java
+++ b/src/Array/layoutFX/HydrophonesPane.java
@@ -1,5 +1,7 @@
package Array.layoutFX;
+import java.util.ArrayList;
+
import Array.Hydrophone;
import Array.PamArray;
import PamController.PamController;
@@ -59,7 +61,12 @@ public class HydrophonesPane extends PamBorderPane {
/**
* Settings pane for a single hydrophone.
*/
- private HydrophoneSettingsPane hydrophonePane = new HydrophoneSettingsPane();
+ private HydrophoneSettingsPane hydrophonePane = new HydrophoneSettingsPane();
+
+ /**
+ * A list of listeners which are called whenever a hydrophone is added removed or changed.
+ */
+ public ArrayList hydrophoneChangeListeners = new ArrayList();
public HydrophonesPane() {
@@ -90,6 +97,8 @@ public class HydrophonesPane extends PamBorderPane {
// System.out.println("Hydro err: " + currentHydrophoneData.getXErr().get()+ " " + currentHydrophoneData.getYErr().get() + " " + currentHydrophoneData.getZErr().get());
currentHydrophoneData.setHydrophone(hydro);
+
+ notifyHydrophoneListeners(currentHydrophoneData);
//need to refresh table to show symbol.
tableArrayPane.getTableView().refresh();
@@ -104,6 +113,16 @@ public class HydrophonesPane extends PamBorderPane {
this.setCenter(pamFlipePane);
}
+ /**
+ * Notify the hydrophone listeners of a change
+ * @param streamer - the changed streamer
+ */
+ public void notifyHydrophoneListeners(HydrophoneProperty hydrophone) {
+ for (ArrayChangeListener listener: hydrophoneChangeListeners) {
+ listener.arrayChanged(ArrayChangeListener.HYDROPHONE_CHANGE, hydrophone);
+ }
+ }
+
/**
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
* @author Jamie Macaulay
diff --git a/src/Array/layoutFX/InterpChoicePane.java b/src/Array/layoutFX/InterpChoicePane.java
index b44b534b..b5e7613b 100644
--- a/src/Array/layoutFX/InterpChoicePane.java
+++ b/src/Array/layoutFX/InterpChoicePane.java
@@ -43,6 +43,8 @@ public class InterpChoicePane extends InterpSettingsPane {
}
public void setSelection(int option) {
+
+ System.out.println("Select interp option: " + option);
interpChoiceBox.getSelectionModel().select(Integer.valueOf(option));
@@ -64,8 +66,13 @@ public class InterpChoicePane extends InterpSettingsPane {
@Override
protected void enableControls() {
+ //get the current selection
+ Integer item = interpChoiceBox.getSelectionModel().getSelectedItem();
+
+ //clear items
interpChoiceBox.getItems().clear();
-
+
+ //set allowed values
for (int i=0; i {
private void enableControls() {
if (currentOriginMethod != null) {
+ System.out.println("Enable: selected interp: " + interpPane.getSelectedInterpType());
+
interpPane.setAllowedValues(currentOriginMethod.getAllowedInterpolationMethods());
+ System.out.println("Enable controls: " + interpPane.getSelectedInterpType());
if (interpPane.getSelectedInterpType()<0) {
interpPane.setSelection(0);
}
@@ -515,7 +518,7 @@ public class StreamerSettingsPane extends SettingsPane {
@Override
public Streamer getParams(Streamer currParams) {
- System.out.println("GETPARAMS: " + currParams);
+// System.out.println("GETPARAMS: " + currParams);
try {
defaultStreamer.setX(Double.valueOf(xPos.getText()));
@@ -532,6 +535,8 @@ public class StreamerSettingsPane extends SettingsPane {
defaultStreamer.setStreamerName(currParams.getStreamerName());
int im = interpPane.getSelectedInterpType();
+ System.out.println("Streamer gwetParams: Origin interpolator: " + interpPane.getSelectedInterpType());
+
if (im < 0) {
System.err.println("Streamer getParams: There is an index problem with the interpolation selection streamer panel: index = " + im);
}
@@ -559,6 +564,7 @@ public class StreamerSettingsPane extends SettingsPane {
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
if (mthDialogComponent != null) {
if (mthDialogComponent.getParams() == false) {
+ System.err.println("Streamer: The origin settings pane returned false suggesting paramters are not correct.");
return null;
}
}
@@ -585,8 +591,8 @@ public class StreamerSettingsPane extends SettingsPane {
* orientation data from or not. The enable orientation check box will enable or
* disable orientation for ALL streamers which are loaded into memory.
*/
- System.out.println("CURRENTORIGINMETHOD: " + currentOriginMethod);
- System.out.println("LOCATORMETHOD: " + locator);
+// System.out.println("CURRENTORIGINMETHOD: " + currentOriginMethod);
+// System.out.println("LOCATORMETHOD: " + locator);
defaultStreamer.setHydrophoneOrigin(currentOriginMethod);
defaultStreamer.setHydrophoneLocator(locator);
@@ -659,20 +665,25 @@ public class StreamerSettingsPane extends SettingsPane {
mthDialogComponent.setParams();
}
- System.out.println("Streamer setParams: Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll());
+// System.out.println("Streamer setParams: Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll());
heading .setText(orientation2Text(defaultStreamer.getHeading()));
pitch .setText(orientation2Text(defaultStreamer.getPitch()));
roll .setText(orientation2Text(defaultStreamer.getRoll()));
- System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation());
+ System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation() + " " + currentOriginMethod.getAllowedInterpolationMethods());
+
if (currentArray.getOriginInterpolation()<0 || currentArray.getOriginInterpolation()>=currentOriginMethod.getAllowedInterpolationMethods()) {
- interpPane.setSelection(0);
+ System.err.println("Streamer setParams: Origin interpolator value of " + currentArray.getOriginInterpolation() + " not allowed for origin method - setting to first allowed method:");
+ interpPane.setSelection(0);
}
else {
interpPane.setSelection(currentArray.getOriginInterpolation());
}
+
+ System.out.println("Streamer setParams: selected interp: " + interpPane.getSelectedInterpType());
+
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
for (int i = 0; i < sensorFields.length; i++) {
@@ -691,7 +702,7 @@ public class StreamerSettingsPane extends SettingsPane {
private String orientation2Text(Double ang) {
if (ang == null) return String.valueOf(0.0);
- else return String.format("%3.1f", defaultStreamer.getHeading());
+ else return String.format("%3.1f", ang);
}
@Override
diff --git a/src/Array/layoutFX/StreamersPane.java b/src/Array/layoutFX/StreamersPane.java
index 97a6cdaf..9cf49bbe 100644
--- a/src/Array/layoutFX/StreamersPane.java
+++ b/src/Array/layoutFX/StreamersPane.java
@@ -1,5 +1,7 @@
package Array.layoutFX;
+import java.util.ArrayList;
+
import Array.PamArray;
import Array.Streamer;
import PamController.PamController;
@@ -10,6 +12,7 @@ import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import pamViewFX.fxNodes.table.TableSettingsPane;
import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
import javafx.scene.layout.Pane;
import javafx.geometry.Insets;
@@ -46,6 +49,11 @@ public class StreamersPane extends PamBorderPane {
*/
private StreamerSettingsPane streamerPane = new StreamerSettingsPane();
+ /**
+ * A list of listeners which are called whenever a streamer is added removed or changed.
+ */
+ public ArrayList streamerChangeListeners = new ArrayList();
+
public StreamersPane() {
@@ -66,15 +74,14 @@ public class StreamersPane extends PamBorderPane {
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
pamFlipePane.setAdvLabelEditable(true);
pamFlipePane.getPostAdvLabel().setText("Settings");
+
pamFlipePane.flipFrontProperty().addListener((obsval, oldVal, newVal)->{
//the flip pane
if (newVal) {
Streamer streamer = streamerPane.getParams(currentStreamerData.getStreamer());
-
- System.out.println("NEW STREAMER: " + streamer);
-
+
if (streamer==null) {
//the warning dialog is shown in the streamer settings pane
return;
@@ -83,6 +90,9 @@ public class StreamersPane extends PamBorderPane {
streamer.setStreamerName(pamFlipePane.getAdvLabel().getText());
currentStreamerData.setStreamer(streamer);
+
+ notifyStreamerListeners(currentStreamerData);
+// System.out.println("Update streamer: " + tableArrayPane.getStreamers().indexOf(currentStreamerData) + " no. streamers: " + currentArray.getNumStreamers());
//need to refresh table to show symbol.
tableArrayPane.getTableView().refresh();
@@ -91,9 +101,7 @@ public class StreamersPane extends PamBorderPane {
streamer.setupLocator(currentArray);
streamer.makeStreamerDataUnit();
//update the streamer in the current array
-// System.out.println("Update streamer: " + tableArrayPane.getStreamers().indexOf(currentStreamerData) + " no. streamers: " + currentArray.getNumStreamers());
}
-
}
});
@@ -101,6 +109,16 @@ public class StreamersPane extends PamBorderPane {
}
+ /**
+ * Notify the streamer listeners of a change
+ * @param streamer - the changed streamer
+ */
+ public void notifyStreamerListeners(StreamerProperty streamer) {
+ for (ArrayChangeListener listener: streamerChangeListeners) {
+ listener.arrayChanged(ArrayChangeListener.STREAMER_CHANGE, streamer);
+ }
+ }
+
/**
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
* @author Jamie Macaulay
@@ -139,7 +157,7 @@ public class StreamersPane extends PamBorderPane {
posColumn.getColumns().addAll(x, y, z);
TableColumn reference = new TableColumn("Reference");
- reference.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
+ reference.setCellValueFactory(cellData -> cellData.getValue().getHydrophoneOrigin());
reference.setEditable(true);
TableColumn locator = new TableColumn("Locator");
@@ -215,7 +233,7 @@ public class StreamersPane extends PamBorderPane {
}
/**
- * Set the paramters for the streamer pane.
+ * Set the parameters for the streamer pane.
* @param currentArray - the current array.
*/
public void setParams(PamArray currentArray) {
@@ -264,5 +282,9 @@ public class StreamersPane extends PamBorderPane {
streamerPane.setRecieverLabels();
}
+ public TableView getStreamerTable() {
+ return tableArrayPane.getTableView();
+ }
+
}
diff --git a/src/Array/streamerOrigin/StaticHydrophonePane.java b/src/Array/streamerOrigin/StaticHydrophonePane.java
index d323e879..fc85a583 100644
--- a/src/Array/streamerOrigin/StaticHydrophonePane.java
+++ b/src/Array/streamerOrigin/StaticHydrophonePane.java
@@ -32,16 +32,20 @@ public class StaticHydrophonePane extends PamBorderPane {
public void setParams() {
GpsDataUnit dataUnit = getStaticOriginSettings().getStaticPosition();
if (dataUnit == null) {
- return;
- }
- GpsData gpsData = dataUnit.getGpsData();
- if (gpsData == null) {
- return;
+ setLatLong(null);
}
else {
+ GpsData gpsData = dataUnit.getGpsData();
setLatLong(gpsData);
}
+// if (gpsData == null) {
+// return;
+// }
+// else {
+// setLatLong(gpsData);
+// }
+
}
private StaticOriginSettings getStaticOriginSettings() {
@@ -50,8 +54,29 @@ public class StaticHydrophonePane extends PamBorderPane {
public boolean getParams() {
- boolean ok = getStaticOriginSettings()!= null && getStaticOriginSettings() .getStaticPosition() != null;
- return ok;
+
+ LatLong latLong = latLongPane.getParams(null);
+
+ if (latLong==null) {
+ System.err.println("StaticHydrophonePane: latitude and longitude is null");
+ return false;
+ }
+
+ if (getStaticOriginSettings()==null) {
+ System.err.println("StaticHydrophonePane: static origin is null");
+ return false;
+ }
+
+ //set
+ getStaticOriginSettings().setStaticPosition(staticOriginMethod.getStreamer(), new GpsData(latLong));
+//
+// boolean ok = getStaticOriginSettings()!= null && getStaticOriginSettings() .getStaticPosition() != null;
+//
+// System.out.println("StaticHydrophonePane: Get params from static origin 1 : " + getStaticOriginSettings());
+//
+// System.out.println("StaticHydrophonePane: Get params from static origin 2: " + getStaticOriginSettings() .getStaticPosition());
+
+ return true;
}
/**
@@ -59,7 +84,14 @@ public class StaticHydrophonePane extends PamBorderPane {
* @param latLong
*/
private void setLatLong(LatLong latLong) {
- latLongPane.setParams(latLong);
+ if (latLong==null) {
+ //create a default latitude and longitude - Rockall (why not).
+ LatLong latLongdefault = new LatLong();
+ latLongdefault.setLatitude(57.595833333333);
+ latLongdefault.setLongitude(-13.686944444444);
+ latLongPane.setParams(latLongdefault);
+ }
+ else latLongPane.setParams(latLong);
}
}
diff --git a/src/Resources/Ishmael_Energy_Sum.svg b/src/Resources/Ishmael_Energy_Sum.svg
new file mode 100644
index 00000000..91103d4c
--- /dev/null
+++ b/src/Resources/Ishmael_Energy_Sum.svg
@@ -0,0 +1,29 @@
+
+
+
+
diff --git a/src/Resources/modules/clicktrain.svg b/src/Resources/modules/clicktrain.svg
new file mode 100644
index 00000000..d7c82592
--- /dev/null
+++ b/src/Resources/modules/clicktrain.svg
@@ -0,0 +1,46 @@
+
+
+
+
diff --git a/src/Resources/modules/detectionDisplay.svg b/src/Resources/modules/detectionDisplay.svg
new file mode 100644
index 00000000..8ed70427
--- /dev/null
+++ b/src/Resources/modules/detectionDisplay.svg
@@ -0,0 +1,32 @@
+
+
+
+
diff --git a/src/Resources/modules/fft.svg b/src/Resources/modules/fft.svg
new file mode 100644
index 00000000..f65bbefc
--- /dev/null
+++ b/src/Resources/modules/fft.svg
@@ -0,0 +1,178 @@
+
+
+
+
diff --git a/src/Resources/modules/filters.svg b/src/Resources/modules/filters.svg
new file mode 100644
index 00000000..8a8ef96c
--- /dev/null
+++ b/src/Resources/modules/filters.svg
@@ -0,0 +1,40 @@
+
+
+
+
diff --git a/src/clickDetector/offlineFuncs/ClickWaveTask.java b/src/clickDetector/offlineFuncs/ClickWaveTask.java
index 49f4368a..a5bfb24c 100644
--- a/src/clickDetector/offlineFuncs/ClickWaveTask.java
+++ b/src/clickDetector/offlineFuncs/ClickWaveTask.java
@@ -131,8 +131,11 @@ public class ClickWaveTask extends OfflineTask {
// setParentDataBlock(clickControl.getClickDataBlock());
addAffectedDataBlock(clickControl.getClickDataBlock());
- rawDataSource = (PamRawDataBlock) clickDetector.getRawSourceDataBlock(clickDetector.getSampleRate());
- daqStatusDataBlock = ((AcquisitionProcess) rawDataSource.getParentProcess()).getDaqStatusDataBlock();
+ rawDataSource = (PamRawDataBlock) clickDetector.getRawSourceDataBlock();
+
+ if (rawDataSource!=null) {
+ daqStatusDataBlock = ((AcquisitionProcess) rawDataSource.getParentProcess()).getDaqStatusDataBlock();
+ }
//TODO- Should not hard wire these but this is not going to be used very often.
filterParams = new FilterParams(FilterType.BUTTERWORTH, FilterBand.HIGHPASS, 250000, 5000, 4);
@@ -155,6 +158,12 @@ public class ClickWaveTask extends OfflineTask {
public void prepareTask() {
Debug.out.println("Load data units from: daqStatusDataBlock: " + daqStatusDataBlock.getUnitsCount());
+ if (daqStatusDataBlock==null) {
+ if (rawDataSource!=null) {
+ daqStatusDataBlock = ((AcquisitionProcess) rawDataSource.getParentProcess()).getDaqStatusDataBlock();
+ }
+ }
+
filterMethod = FilterMethod.createFilterMethod(clickDetector.getSampleRate(), filterParams);
daqStatusDataBlock.loadViewerData(new OfflineDataLoadInfo(clickControl.getClickDataBlock().getFirstUnit().getTimeMilliseconds()-DEFAULTDAQUNITLOAD,
diff --git a/src/clickDetector/offlineFuncs/ClicksOffline.java b/src/clickDetector/offlineFuncs/ClicksOffline.java
index 4423c721..6628595e 100644
--- a/src/clickDetector/offlineFuncs/ClicksOffline.java
+++ b/src/clickDetector/offlineFuncs/ClicksOffline.java
@@ -587,10 +587,10 @@ public class ClicksOffline {
offlineTaskGroup.addTask(new EchoDetectionTask(clickControl));
offlineTaskGroup.addTask(new ClickDelayTask(clickControl));
offlineTaskGroup.addTask(new ClickBearingTask(clickControl));
- if (JamieDev.isEnabled()) {
- //re import waveform data from raw wave files.
- offlineTaskGroup.addTask(new ClickWaveTask(clickControl));
- }
+// if (JamieDev.isEnabled()) {
+// //re import waveform data from raw wave files.
+// offlineTaskGroup.addTask(new ClickWaveTask(clickControl));
+// }
/*
* Add the click detector tasks first since these will need to operate
diff --git a/src/dataModelFX/connectionNodes/ModuleIconFactory.java b/src/dataModelFX/connectionNodes/ModuleIconFactory.java
index 50bcf046..cab1f84e 100644
--- a/src/dataModelFX/connectionNodes/ModuleIconFactory.java
+++ b/src/dataModelFX/connectionNodes/ModuleIconFactory.java
@@ -55,16 +55,19 @@ public class ModuleIconFactory {
// return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/click.png")));
return getSVGIcon("/Resources/modules/Click Detector Icon.svg", Color.BLACK, 2);
case CLICK_TRAIN:
- return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/clicktrain.png")));
+// return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/clicktrain.png")));
+ return getSVGIcon("/Resources/modules/clicktrain.svg",Color.BLACK, 2);
case DATABASE:
// return PamGlyphDude.createModuleGlyph(FontAwesomeIcon.DATABASE);
return PamGlyphDude.createModuleIcon("mdi2d-database");
case DATAMAP:
return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/dataMap.png")));
case FFT:
- return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/fft.png")));
+// return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/fft.png")));
+ return getSVGIcon("/Resources/modules/fft.svg",Color.BLACK, 2);
case FILTER:
- return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/filters.png")));
+// return new ImageView(new Image(getClass().getResourceAsStream("/Resources/modules/filters.png")));
+ return getSVGIcon("/Resources/modules/filters.svg",Color.BLACK, 2);
case GPS:
// return PamGlyphDude.createModuleGlyph(MaterialIcon.GPS_FIXED);
return PamGlyphDude.createModuleIcon("mdi2c-crosshairs-gps");
@@ -126,8 +129,8 @@ public class ModuleIconFactory {
PamSVGIcon iconMaker= new PamSVGIcon();
PamSVGIcon svgsprite = iconMaker.create(getClass().getResource(resourcePath).toURI().toURL(), colour, lineWidth);
- svgsprite.getSpriteNode().setStyle("-fx-text-color: black");
- svgsprite.getSpriteNode().setStyle("-fx-fill: black");
+// svgsprite.getSpriteNode().setStyle("-fx-text-color: black");
+// svgsprite.getSpriteNode().setStyle("-fx-fill: black");
svgsprite.setFitHeight(DataModelStyle.iconSize-10);
svgsprite.setFitWidth(DataModelStyle.iconSize-10);
diff --git a/src/pamViewFX/PamSettingsMenuPane.java b/src/pamViewFX/PamSettingsMenuPane.java
index caafe3a4..50d5e715 100644
--- a/src/pamViewFX/PamSettingsMenuPane.java
+++ b/src/pamViewFX/PamSettingsMenuPane.java
@@ -208,17 +208,20 @@ public class PamSettingsMenuPane extends PamVBox {
PamButton about=new PamButton("About...");
styleButton(about);
- PamButton tip=new PamButton("Tip of the day...");
- styleButton(tip);
+// PamButton tip=new PamButton("Tip of the day...");
+// styleButton(tip);
PamButton website=new PamButton("Website");
styleButton(website);
- PamButton contact=new PamButton("Contact and Support");
+ PamButton contact=new PamButton("Found a bug?");
+ styleButton(contact);
+
+ PamButton checkForUpdates=new PamButton("Check for updates");
styleButton(contact);
this.getChildren().addAll(settingsLabel,saveConfig,saveConfigAs, new Separator(), mediumToggleBox, generalSettings, settings, new Separator(),
- storageManager, database, binaryStorage, new Separator(), help, about, tip, website, contact);
+ storageManager, database, binaryStorage, new Separator(), help, checkForUpdates, website, contact, about);
}
diff --git a/src/pamViewFX/fxGlyphs/PamSVGIcon.java b/src/pamViewFX/fxGlyphs/PamSVGIcon.java
index 74149268..9f9c3b96 100644
--- a/src/pamViewFX/fxGlyphs/PamSVGIcon.java
+++ b/src/pamViewFX/fxGlyphs/PamSVGIcon.java
@@ -4,6 +4,7 @@ import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
+import javafx.scene.shape.FillRule;
import javafx.scene.shape.SVGPath;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
@@ -65,9 +66,9 @@ public class PamSVGIcon {
public PamSVGIcon create(URL path, Color color, double lineWidth) throws Exception {
-// System.out.println("Create icon start");
+ // System.out.println("Create icon start");
- String col = PamUtilsFX.toRGBCode(color);
+// String col = PamUtilsFX.toRGBCode(color);
// System.out.println("Create icon getDocument()");
@@ -87,14 +88,27 @@ public class PamSVGIcon {
for(int i=0; i{
- // System.out.println("FLIP BACK TO FRONT");
- this.flipToFront();
- });
-
+
//make the back button blue so users can easily see the button.
backButton.setStyle("-fx-background-radius: 0 5 5 0; -fx-border-radius: 0 5 5 0; -fx-background-color: -color-accent-6");
+ backButton.setOnAction((action)->{
+ // System.out.println("FLIP BACK TO FRONT");
+ this.backButtonResponse.setValue(OK_BACK_BUTTON);
+ this.flipToFront();
+ });
+
+ //Allow the user to cancel instead of pressing back button to confirm.
+ ContextMenu contextMenu = new ContextMenu();
+ //Creating the menu Items for the context menu
+ MenuItem item1 = new MenuItem("Cancel");
+ item1.setStyle("-fx-background-color: red");
+ contextMenu.setStyle("-fx-background-color: red");
+ item1.setOnAction((action)->{
+ // System.out.println("FLIP BACK TO FRONT");
+ this.backButtonResponse.setValue(CANCEL_BACK_BUTTON);
+ this.flipToFront();
+ });
+ contextMenu.getItems().addAll(item1);
+
+ backButton.setContextMenu(contextMenu);
+
+ //create a title that can be set.
//backButton.setPrefWidth(150);
PamBorderPane advPane = new PamBorderPane();
//advPane.setPadding(new Insets(5,5,5,5));
-
-
+
// holds the title of the advanced pane. This consists of a label for a graphic,
// an editable text field and a label after the editable settings field
PamHBox titleHolder = new PamHBox();
@@ -158,27 +193,27 @@ public class PamFlipPane extends FlipPane {
postLabel.setAlignment(Pos.CENTER_LEFT);
advLabel.setAlignment(Pos.CENTER);
-// advLabel.prefColumnCountProperty().bind(advLabel.textProperty().length().subtract(3));
+ // advLabel.prefColumnCountProperty().bind(advLabel.textProperty().length().subtract(3));
// Set Max and Min Width to PREF_SIZE so that the TextField is always PREF
advLabel.setMinWidth(Region.USE_PREF_SIZE);
advLabel.setMaxWidth(Region.USE_PREF_SIZE);
-
+
//pretty complicated to make sure the text field is the same size as the text that is being typed.
advLabel.textProperty().addListener((ov, prevText, currText) -> {
- // Do this in a Platform.runLater because of Textfield has no padding at first time and so on
- Platform.runLater(() -> {
- Text text = new Text(currText);
- text.setFont(advLabel.getFont()); // Set the same font, so the size is the same
- double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
- + advLabel.getPadding().getLeft() + advLabel.getPadding().getRight() // Add the padding of the TextField
- + 2d; // Add some spacing
- advLabel.setPrefWidth(width); // Set the width
- advLabel.positionCaret(advLabel.getCaretPosition()); // If you remove this line, it flashes a little bit
- });
+ // Do this in a Platform.runLater because of Textfield has no padding at first time and so on
+ Platform.runLater(() -> {
+ Text text = new Text(currText);
+ text.setFont(advLabel.getFont()); // Set the same font, so the size is the same
+ double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
+ + advLabel.getPadding().getLeft() + advLabel.getPadding().getRight() // Add the padding of the TextField
+ + 2d; // Add some spacing
+ advLabel.setPrefWidth(width); // Set the width
+ advLabel.positionCaret(advLabel.getCaretPosition()); // If you remove this line, it flashes a little bit
+ });
});
advLabel.setId("label-title2");
advLabel.setStyle("-fx-background-color: transparent");
-
+
titleHolder.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
//holds the back button and the title pane.
@@ -190,31 +225,31 @@ public class PamFlipPane extends FlipPane {
advLabel.setAlignment(Pos.CENTER);
advLabel.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
-// PamGuiManagerFX.titleFont2style(advLabel);
+ // PamGuiManagerFX.titleFont2style(advLabel);
advLabel.setAlignment(Pos.CENTER);
HBox.setHgrow(titleHolder, Priority.ALWAYS);
-
+
advPane.setTop(buttonHolder);
-
+
return advPane;
-
+
}
-
+
public TextField getAdvLabel() {
return advLabel;
}
-// public void setAdvLabel(Label advLabel) {
-// this.advLabel = advLabel;
-// }
+ // public void setAdvLabel(Label advLabel) {
+ // this.advLabel = advLabel;
+ // }
public PamButton getBackButton() {
return backButton;
}
-
+
/**
* Get the label located before the editable label in the title
* @return the label before the editable label
@@ -222,7 +257,7 @@ public class PamFlipPane extends FlipPane {
public Label getPreAdvLabel() {
return preLabel;
}
-
+
/**
* Get the label located after the editable label in the title
* @return the label after the editable label
@@ -240,7 +275,7 @@ public class PamFlipPane extends FlipPane {
public void setAdvLabelEditable(boolean b) {
this.advLabel.setEditable(b);
-
+
}
diff --git a/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java b/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java
index 711491dd..a628221b 100644
--- a/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java
+++ b/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java
@@ -56,16 +56,17 @@ public class LatLongPane extends SettingsPane{
public LatLongPane(String title) {
super(null);
-
-
+
+
mainPane = new PamVBox();
mainPane.setSpacing(5);
mainPane.setAlignment(Pos.CENTER);
-
+
Label titleLabel = new Label(title);
titleLabel.maxWidth(Double.MAX_VALUE);
titleLabel.setTextAlignment(TextAlignment.LEFT);
+ titleLabel.setAlignment(Pos.CENTER_LEFT);
PamGuiManagerFX.titleFont2style(titleLabel);
mainPane.getChildren().add(titleLabel);
@@ -109,7 +110,7 @@ public class LatLongPane extends SettingsPane{
cent.getChildren().add(latStrip = new LatLongStrip(true));
cent.getChildren().add(longStrip = new LatLongStrip(false));
-
+
//bit of a hack that makes sure controls are aligned for the latitude and longitude.
latStrip.getTitleLabel().prefWidthProperty().bind(longStrip.getTitleLabel().widthProperty());
@@ -123,46 +124,24 @@ public class LatLongPane extends SettingsPane{
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(javafx.event.ActionEvent action) {
-
-
- if (action.getSource() == decimalMinutes) {
- LatLong.setFormatStyle(LatLong.FORMAT_DECIMALMINUTES);
- // if (latStrip != null) {
- // latStrip.setDecimalMinutes(true);
- // longStrip.setDecimalMinutes(true);
- // }
- latStrip.showControls(LatLong.FORMAT_DECIMALMINUTES);
- longStrip.showControls(LatLong.FORMAT_DECIMALMINUTES);
- }
- else if (action.getSource() == minutesSeconds){
- LatLong.setFormatStyle(LatLong.FORMAT_MINUTESSECONDS);
- // if (latStrip != null) {
- // latStrip.setDecimalMinutes(false);
- // longStrip.setDecimalMinutes(false);
- //// latStrip.showControls();
- //// longStrip.showControls();
- // }
- latStrip.showControls(LatLong.FORMAT_MINUTESSECONDS);
- longStrip.showControls(LatLong.FORMAT_MINUTESSECONDS);
- }
- else if (action.getSource() == decimal){
- LatLong.setFormatStyle(LatLong.FORMAT_DECIMAL);
- latStrip.showControls(LatLong.FORMAT_DECIMAL);
- longStrip.showControls(LatLong.FORMAT_DECIMAL);
- }
-
+
+ int format = getSelectedLatLongFormat();
+
+ LatLong.setFormatStyle(format);
+ latStrip.showControls(format);
+ longStrip.showControls(format);
}
private void showLatLong() {
-
+
decimalMinutes .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_DECIMALMINUTES);
minutesSeconds .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_MINUTESSECONDS);
decimal .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_DECIMAL);
- latStrip .showControls(LatLong.getFormatStyle() );
- longStrip .showControls(LatLong.getFormatStyle() );
+ latStrip .showControls(LatLong.getFormatStyle());
+ longStrip .showControls(LatLong.getFormatStyle());
latStrip .setValue(latLong.getLatitude());
longStrip .setValue(latLong.getLongitude());
}
@@ -174,21 +153,11 @@ public class LatLongPane extends SettingsPane{
*/
@Override
public LatLong getParams(LatLong currentParams) {
-
- Toggle selectedButton = this.segmentedButton.getToggleGroup().getSelectedToggle();
-
- if (selectedButton == decimalMinutes) {
- LatLong.setFormatStyle(LatLong.FORMAT_DECIMALMINUTES);
- }
- else if (selectedButton == minutesSeconds){
- LatLong.setFormatStyle(LatLong.FORMAT_MINUTESSECONDS);
-
- }
- else if (selectedButton == decimal){
- LatLong.setFormatStyle(LatLong.FORMAT_DECIMAL);
- }
-
+ int format = getSelectedLatLongFormat();
+
+ LatLong.setFormatStyle(format);
+
latLong = new LatLong(latStrip.getValue(), longStrip.getValue());
if (Double.isNaN(latLong.getLatitude()) || Double.isNaN(latLong.getLongitude())) {
return null;
@@ -196,6 +165,26 @@ public class LatLongPane extends SettingsPane{
return latLong;
}
+ /**
+ * Get the selected format for showing latitude and longitude values.
+ * @return the selected format flag or -1 if no format is selected.
+ */
+ private int getSelectedLatLongFormat() {
+ Toggle selectedButton = this.segmentedButton.getToggleGroup().getSelectedToggle();
+ if (selectedButton == decimalMinutes) {
+ return LatLong.FORMAT_DECIMALMINUTES;
+
+ }
+ else if (selectedButton == minutesSeconds){
+ return LatLong.FORMAT_MINUTESSECONDS;
+
+ }
+ else if (selectedButton == decimal){
+ return LatLong.FORMAT_DECIMAL;
+ }
+ return -1;
+ }
+
@Override
public void setParams(LatLong input) {
this.latLong=input;
diff --git a/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java b/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java
index 2e80e8f0..915de2d9 100644
--- a/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java
+++ b/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java
@@ -12,7 +12,7 @@ import pamViewFX.fxNodes.PamHBox;
/**
* A pane which shows a latitude or longitude. Allows users to enter data as decimal or minutes/seconds.
- * (copied ot FX from Doug Gillespie's LatLongDialogStrip)
+ * (copied to FX from Doug Gillespie's LatLongDialogStrip)
* @author Jamie Macaulay
*
*/
@@ -39,6 +39,7 @@ public class LatLongStrip extends PamBorderPane {
* The format type e.g. LatLong.FORMAT_DECIMALMINUTES.
*/
private int formatType = LatLong.FORMAT_DECIMALMINUTES;
+
private Label titleLabel;
@@ -152,7 +153,7 @@ public class LatLongStrip extends PamBorderPane {
this.setCenter(holder);
this.setBottom(formattedText);
- showControls(formatType);
+ showControls(formatType, true);
}
private void newTypedValues(KeyEvent e) {
@@ -170,10 +171,25 @@ public class LatLongStrip extends PamBorderPane {
// and say the formated version
sayFormattedValue(v);
}
-
+
+
+ /**
+ * Change the current controls for to show to show the current format of Latitude or Longitude.
+ * @param formatStyle - the style of Latitude or longitude e.g. LatLong.FORMAT_DECIMALMINUTES;
+ */
public void showControls(int formatStyle) {
- if (formatType==formatStyle) {
+ showControls(formatStyle, false);
+ }
+
+ /**
+ * Change the current controls for to show to show the current format of Latitude or Longitude.
+ * @param force - force a reset of controls even if the format style is the same as the current style.
+ * @param formatStyle - the style of Latitude or longitude e.g. LatLong.FORMAT_DECIMALMINUTES;
+ */
+ private void showControls(int formatStyle, boolean force) {
+
+ if (formatType==formatStyle && !force) {
return;
}
@@ -223,7 +239,7 @@ public class LatLongStrip extends PamBorderPane {
public void setValue(double value, boolean hiddenOnly) {
- System.out.println("Set value: " + value);
+// System.out.println("Set value: " + value);
if (value >= 0) {
nsew.getSelectionModel().select(0);
}