Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
3206 lines (2832 loc) · 95 KB

File metadata and controls

3206 lines (2832 loc) · 95 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* PAMGUARD - Passive Acoustic Monitoring GUARDianship.
* To assist in the Detection Classification and Localisation
* of marine mammals (cetaceans).
*
* Copyright (C) 2006
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package PamController;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess;
import Array.ArrayManager;
import PamController.command.MulticastController;
import PamController.command.NetworkController;
import PamController.command.TerminalController;
import PamController.command.WatchdogComms;
import PamController.fileprocessing.ReprocessManager;
import PamController.fileprocessing.ReprocessManagerMonitor;
import PamController.masterReference.MasterReferencePoint;
import PamController.pamWizard.PamWizardManager;
import PamController.settings.BatchViewSettingsImport;
import PamController.settings.output.xml.XMLWriterDialog;
import PamController.soundMedium.GlobalMediumManager;
import PamDetection.PamDetection;
import PamDetection.RawDataUnit;
import PamModel.PamModel;
import PamModel.PamModelSettings;
import PamModel.PamModuleInfo;
import PamModel.SMRUEnable;
import PamUtils.PamCalendar;
import PamUtils.time.GlobalTimeManager;
import PamView.GeneralProjector;
import PamView.GuiFrameManager;
import PamView.PamColors;
import PamView.PamView;
import PamView.PamViewInterface;
import PamView.TopToolBar;
import PamView.dialog.warn.WarnOnce;
import PamView.paneloverlay.overlaymark.MarkRelationships;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import PamguardMVC.PamRawDataBlock;
import PamguardMVC.dataSelector.DataSelectorCreator;
import PamguardMVC.datakeeper.DataKeeper;
import PamguardMVC.uid.UIDManager;
import PamguardMVC.uid.UIDOnlineManager;
import PamguardMVC.uid.UIDViewerManager;
import binaryFileStorage.BinaryStore;
import export.ExportOptions;
import fftManager.FFTDataUnit;
import generalDatabase.DBControlUnit;
import javafx.application.Platform;
import javafx.stage.Stage;
import metadata.MetaDataContol;
import offlineProcessing.OfflineTaskManager;
//import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
//import com.sun.org.apache.xml.internal.serialize.OutputFormat;
//import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import pamScrollSystem.AbstractScrollManager;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.pamTask.PamTaskUpdate;
import pamguard.GlobalArguments;
import pamguard.Pamguard;
import soundPlayback.PlaybackControl;
import warnings.PamWarning;
import warnings.WarningSystem;
import zipUnpacker.ZipUnpacker;
/**
* @author Doug Gillespie
* <p>
* Main Pam Controller class which will communicate with the
* PamModelInterface and with the PamViewInterface
* <p>
* PamController contains a list of PamControlledUnit's each of which
* has it's own process,
* simpleMapRef.gpsTextPanel.setPixelsPerMetre(getPixelsPerMetre());
* input and output data and display (Tab Panel, Menus, etc.)
* @see PamController.PamControlledUnit
* @see PamView.PamTabPanel
*
*/
public class PamController implements PamControllerInterface, PamSettings {
// status can depend on the run mode !
public static final int PAM_IDLE = 0;
public static final int PAM_RUNNING = 1;
public static final int PAM_STALLED = 3;
public static final int PAM_INITIALISING = 4;
public static final int PAM_STOPPING = 5;
public static final int PAM_COMPLETE = 6;
public static final int PAM_MAPMAKING = 7;
public static final int PAM_OFFLINETASK = 8;
public static final int BUTTON_START = 1;
public static final int BUTTON_STOP = 2;
private volatile int lastStartStopButton = 0;
// status' for RunMode = RUN_PAMVIEW
public static final int PAM_LOADINGDATA = 2;
public static final int RUN_NORMAL = 0;
public static final int RUN_PAMVIEW = 1;
public static final int RUN_MIXEDMODE = 2;
public static final int RUN_REMOTE = 3;
public static final int RUN_NOTHING = 4;
public static final int RUN_NETWORKRECEIVER = 5;
private int runMode = RUN_NORMAL;
// flag used in main() to indicate that processing should start immediately.
public static final String AUTOSTART = "-autostart";
// flag used in main() to indicate that pamguard should exit as soon as
// processing ends.
public static final String AUTOEXIT = "-autoexit";
/**
* Never changed. Needed to identify settings for list of modules in prfx files.
*/
public static final String unitName = "Pamguard Controller";
public static final String unitType = "PamController";
/**
* The pam model.
*/
private PamModel pamModelInterface;
private PamConfiguration pamConfiguration;
/**
* The current PAM status
*/
private volatile int pamStatus = PAM_IDLE;
/**
* PamGuard view params.
*/
public PamViewParameters pamViewParameters = new PamViewParameters();
// ViewerStatusBar viewerStatusBar;
/*
* Swing GUI manager
*/
private PAMControllerGUI guiFrameManager;
/**
* Indicates whether initialisation has completed
*/
private boolean initializationComplete = false;
/**
* The java version being run. e.g. Java 8u111 will be 8.111;
*/
public static double JAVA_VERSION = getVersion();
// PAMGUARD CREATION IS LAUNCHED HERE !!!
// private static PamControllerInterface anyController = new PamController();
private static PamController uniqueController;
private Timer diagnosticTimer;
private boolean debugDumpBufferAtRestart = false;
private NetworkController networkController;
private int nNetPrepared;
private int nNetStarted;
private int nNetStopped;
private Timer garbageTimer;
/**
* The UID manager.
*/
private UIDManager uidManager;
/**
* A global time manager to manage corrections to the PC clock from various
* sources.
*/
private GlobalTimeManager globalTimeManager;
/**
* A global medium manager which handles the type of medium sound is propogating
* through.
*/
private GlobalMediumManager globalMediumManager;
/**
* Manager for PamWizard functionality
*/
private PamWizardManager pamWizardManager;
/**
* A reference to the module currently being loaded. Used by the
* PamExceptionHandler to monitor runtime errors that occur during load
*/
private static PamControlledUnit unitBeingLoaded = null;
/**
* Folder where Pamguard is installed and running out of. This string includes
* the file separator at the end, or is null if there was a problem trying to
* determine the installation folder
*/
private String installFolder = null;
private boolean haveGlobalTimeUpdate;
private WatchdogComms watchdogComms;
private PamWarning statusWarning = new PamWarning("PAMGuard control", "Status", 0);
/**
* A separate thread that checks all ThreadedObservers to see if they still have
* data in their buffers
*/
private Thread statusCheckThread;
private WaitDetectorThread detectorEndThread;
private boolean firstDataLoadComplete;
// keep a track of the total number of times PAMGuard is started for debug
// purposes.
private int nStarts;
private RestartRunnable restartRunnable;
private boolean batchFirst = true; // flag for starting batch offline tasks.
/**
* Subclass of URLClassLoader, to handle loading of plugins
*/
// private static PluginClassloader classLoader;
private PamController(int runMode, Object object) {
uniqueController = this;
pamConfiguration = new PamConfiguration();
this.runMode = runMode;
if (runMode == PamController.RUN_PAMVIEW) {
uidManager = new UIDViewerManager(this);
} else {
uidManager = new UIDOnlineManager(this);
}
sayMemory();
globalTimeManager = new GlobalTimeManager(this);
globalMediumManager = new GlobalMediumManager(this);
pamWizardManager = new PamWizardManager(this);
setPamStatus(PAM_IDLE);
watchdogComms = new WatchdogComms(this);
if (pamBuoyGlobals.getNetworkControlPort() != null) {
networkController = new NetworkController(this);
}
if (pamBuoyGlobals.getMulticastAddress() != null) {
new MulticastController(this);
}
guiFrameManager = PamGUIManager.createGUI(this, object);
guiFrameManager.init(); // perform any start up processes for the GUI.
installFolder = getInstallLocation();
setupPamguard();
setupGarbageCollector();
// if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
// }
// diagnosticTimer = new Timer(1000, new DiagnosticTimer());
// diagnosticTimer.start();
}
/**
* Get the location of the install folder. Note that this will be system dependent.
* @return the location of the install folder.
*/
private String getInstallLocation() {
// figure out the installation folder
String installFolder = null;
try {
File theURL = new File(
this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
installFolder = theURL.getParentFile().getPath() + File.separator;
} catch (URISyntaxException e) {
System.out.println("Error finding installation folder of jar file: " + e.getMessage());
e.printStackTrace();
installFolder = null;
}
//if a Mac AND we are inside the applications folder then
if (System.getProperty("os.name").startsWith("Mac")) {
String macAppFolder = new String("/Applications/PAMGuard.app/Contents");
if (installFolder.startsWith(macAppFolder)) {
//PAMGuard is running form a .app bundle in the Applications directory on macOS
installFolder = macAppFolder + File.separator;
}
//otherwise the install folder stays the same as we are using an IDE
}
return installFolder;
}
class DiagnosticTimer implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
sayMemory();
}
}
private void sayMemory() {
Runtime r = Runtime.getRuntime();
System.out.println(String.format("System memory at %s Max %d, Free %d",
PamCalendar.formatDateTime(System.currentTimeMillis()), r.maxMemory(), r.freeMemory()));
}
/**
* Create an instance of the PAMController.
*
* @param runMode - the run mode
*/
public static void create(int runMode) {
if (uniqueController == null) {
PamController pamcontroller = new PamController(runMode, null);
/*
* I don't see any reason not have have this running with the GUI. It launches
* in a new thread, so it should be fine to have additional commands afterwards.
*/
TerminalController tc = new TerminalController(pamcontroller);
tc.getTerminalCommands();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
uniqueController.creationComplete();
}
});
}
/**
* Not to sound God like, but this will be called on the AWT dispatch thread
* shortly after all modules are created, PAMGuard should be fully setup and all
* modules will have received INITIALISATION_COMPLETE and should be good to run
*/
private void creationComplete() {
MarkRelationships.getInstance().subscribeAllMarkers();
if (GlobalArguments.getParam(PamController.AUTOSTART) != null) {
if (getRunMode() == RUN_NORMAL) {
startLater(); // may as well give AWT time to loop it's queue once more
}
else if (getRunMode() == RUN_PAMVIEW) {
startOfflineTasks();
}
}
else {
}
}
/**
* Called when batch processing offline tasks from the AUTOSTART functions.
* Will start an offline task controller, which will then work it's way through
* the groups of tasks.
*/
public void startOfflineTasks() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
OfflineTaskManager.getManager().startBatchTasks();
}
});
}
/**
* Create an instance of the PAMcController.
*
* @param runMode - the run mode
* @param object - extra information. Can be null.
*/
public static void create(int runMode, Object object) {
if (uniqueController == null) {
new PamController(runMode, object);
}
}
/**
* Setup the PAMController.
*/
public void setupPamguard() {
/**
* Set Locale to English so that formated writes to text fields in dialogs use .
* and not , for the decimal.
*/
Locale.setDefault(Locale.ENGLISH);
/*
* 15/8/07 Changed creation order of model and view. Need to be able to create a
* database pretty early on (in the Model) in order to read back settings that
* the GUI may require.
*
*/
// create the model
pamModelInterface = new PamModel(this);
pamModelInterface.createPamModel();
/*
* 9 February 2009 Trying to sort out settings file loading. Was previously done
* when the first modules registered itself with the settings manager. Gets very
* confusing. Will be much easier to load up the settings first, depending on
* the type of module and then have them ready when the modules start asking for
* them.
*/
int loadAns = PamSettingManager.getInstance().loadPAMSettings(runMode);
System.out.println("Pamcontroller: loadPAMSettings: " + loadAns);
if (loadAns == PamSettingManager.LOAD_SETTINGS_NEW) {
// if (runMode == RUN_PAMVIEW) {
// // no model, no gui, so PAMGAURD will simply exit.
// String str = String.format("PAMGUARD cannot run in %s mode without a valid
// database\nPAMGUARD will exit.",
// getRunModeName());
// str = "You have opened a database in viewer mode that contains no settings\n"
// +
// "Either load settings from the binary store, import a psf settings file or
// create modules by hand.\n" +
// "Press OK to continue or Cancel to exit the viewer";
//
// int ans = JOptionPane.showConfirmDialog(null, str, "PAMGuard viewer",
// JOptionPane.OK_CANCEL_OPTION);
// if (ans == JOptionPane.CANCEL_OPTION) {
// System.exit(0);
// }
// }
// else if (loadAns == ){
// // normal settings will probably return an error, but it's OK still !
//// System.exit(0);
// }
// return;
} else if (loadAns == PamSettingManager.LOAD_SETTINGS_CANCEL) {
JOptionPane.showMessageDialog(null, "No settings loaded. PAMGuard will exit", "PAMGuard",
JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
if (getRunMode() == RUN_NOTHING) {
return;
}
// get the general settings out of the file immediately.
// PamSettingManager.getInstance().loadSettingsFileData();
/*
* prepare to add a database to the model. this will then re-read it's settings
* from the settings file - which we dont' want yet !!!!! But now we have the
* database, it should be possible to alter the code that reads in all settings
* from a selected file and alter it so it gets them from the db instead. Then
* remove this database module immediately and let Pamguard create a new one
* based on the settings !
*/
// PamModuleInfo mi = PamModuleInfo.findModuleInfo("generalDatabase.DBControl");
// PamControlledUnitSettings dbSettings =
// PamSettingManager.getInstance().findGeneralSettings(DBControl.getDbUnitType());
// if (mi != null) {
// addModule(mi, "Temporary Database");
// }
// Add a note to the output console for the user to ignore the SLF4J warning
// (see http://www.slf4j.org/codes.html#StaticLoggerBinder
// for details). I spent a few hours trying to get rid of this warning, but
// without any luck. If you do a google search
// there are a lot of forum suggestions on how to fix, but none seemed to work
// for me. Added both slf4j-nop and
// slf4j-simple to dependency list, neither made a difference. Changed order of
// dependencies, ran purges and updates,
// added slf4j-api explicitly, made sure I don't have duplicate bindings, but
// nothing helped.
//
// Error occurs when PamDataBlock.sortTypeInformation() calls
// superDetectionClass = GenericTypeResolver.resolveReturnType(method,
// unitClass); (currently line 397). I don't want
// to add the note there because that gets called every time a PamDataBlock is
// created. So I add the note here, which
// is just before the error occurs
//
// Oddly enough, this warning DOES NOT occur when running the non-Maven version
// (Java12 branch). The dependencies in the
// classpath are the same as the ones here in Maven, so I don't know what to
// say.
System.out.println("");
System.out.println(
"Note - ignore the following SLF4J warn/error messages, they are not applicable to this application");
ArrayManager.getArrayManager(); // create the array manager so that it get's it's settings
MetaDataContol.getMetaDataControl();
/**
* Check for archived files and unpack automatically.
*/
if (runMode == RUN_PAMVIEW && SMRUEnable.isEnable()) {
ZipUnpacker zipUnpacker = new ZipUnpacker(this);
zipUnpacker.checkforFiles();
}
// create the view
// Worldwind Map removed 2017/05/05 because the worldwind.jar library duplicates
// the jsonNode class in jackson-all-1.9.9.jar library, but
// it isn't the same. While Eclipse can keep it straight and use class info from
// jackson instead of worldmap, the PamguardCompiler installer
// seems to want to use the worldmap instead (even though the classes are listed
// correctly). This causes problems when Pamguard tries to
// load a database with click events that have an error message in them. It
// simply stops reading the database when it hits an error message,
// but does not throw any sort of error itself.
// If we want to reinstate Worldwind Map, this duplication of code needs to be
// resolved.
// if (SMRUEnable.isEnable()) {
// try {
// Class.forName("worldWindMap.WorldMapProvider");
// } catch (ClassNotFoundException e) {
//// // TODO Auto-generated catch block
//// e.printStackTrace();
// }
// }
/*
* We are running as a remote application, start process straight away!
*/
if (!PamSettingManager.RUN_REMOTE) {
addView(guiFrameManager.initPrimaryView(this, pamModelInterface));
}
/**
* Calling this will cause a callback to this.restoreSettings which includes a
* list of modules which will then get created, and in turn load all of their
* own settings from the settings manager.
*/
PamSettingManager.getInstance().registerSettings(this);
/**
* For offline batch processing a few funnies happen here. We'll be open in
* viewer mode, but it's likely a psf will have been passed as an input
* argument. We will therefore have to extract all the modules from that psfx as
* well and either add them as new modules, or get their settings and use those
* to update existing settings That should probably be done here before the
* final calls to setup processes, etc.
*/
// if (getRunMode() == RUN_PAMVIEW && PamSettingManager.remote_psf != null) {
// loadOtherSettings(PamSettingManager.remote_psf);
// }
/*
* Get any other required modules for this run mode.
*/
pamModelInterface.startModel();
setupProcesses();
/*
* We are running as a remote application, start process straight away!
*/
if (getRunMode() == RUN_NOTHING) {
} else if (PamSettingManager.RUN_REMOTE) {
// Initialisation is complete.
initializationComplete = true;
notifyModelChanged(PamControllerInterface.INITIALIZATION_COMPLETE);
System.out.println("Starting Pamguard in REMOTE execution mode.");
pamStart();
} else {
// if (getRunMode() == RUN_PAMVIEW) {
// createViewerStatusBar();
// }
// call before initialisation complete, so that processes can re-do.
createAnnotations();
organiseGUIFrames();
// sort the frame titles (Swing convenience)
if (PamGUIManager.isSwing())
sortFrameTitles();
initializationComplete = true;
notifyModelChanged(PamControllerInterface.INITIALIZATION_COMPLETE);
/**
* Trigger loading of relationships between markers and mark observers. No need
* to do anything more than call the constructor and everything else will
* happen...
*/
MarkRelationships.getInstance();
}
if (getRunMode() == RUN_PAMVIEW) {
/**
* Tell any modules implementing OfflineDataSource to check their maps.
*/
AWTScheduler.getInstance().scheduleTask(new DataInitialised());
// PamControlledUnit pcu;
// OfflineDataSource offlineDataSource;
// for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
// pcu = pamControlledUnits.get(iU);
// if (OfflineDataSource.class.isAssignableFrom(pcu.getClass())) {
// offlineDataSource = (OfflineDataSource) pcu;
// offlineDataSource.createOfflineDataMap(null);
// }
// }
// PamSettingManager.getInstance().registerSettings(new ViewTimesSettings());
// getNewViewTimes(null);
}
uidManager.runStartupChecks();
clearSelectorsAndSymbols();
/**
* Debug code for starting PG as soon as it's initialised.
*/
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// pamStart();
// }
// });
}
/**
* Clear all data selectors and symbol managers. Required since some of these
* will have loaded as various modules were created, but may also require
* additional data selectors and symbol managers from super detections which
* were not availble. Deleting the lot, will cause them to be recreated as soon
* as they are next needed. Should probably also call these on any call to
* addModule as well ?
*/
private void clearSelectorsAndSymbols() {
DataSelectorCreator.globalClear();
PamSymbolManager.globalClear();
}
/**
* This gets called after other data initialisation tasks (such as data
* mapping).
*
* @author dg50
*
*/
class DataInitialised implements Runnable {
@Override
public void run() {
notifyModelChanged(PamControllerInterface.INITIALIZE_LOADDATA);
// tell all scrollers to reload their data.
// loadViewerData();
}
}
/**
* Called when the number of Networked remote stations changes so that the
* receiver can make a decision as to what to do in terms of preparing
* detectors, opening files, etc.
*
* @param timeMilliseconds
* @param nPrepared number of remote stations currently prepared (called
* just before start)
* @param nStarted number of remote stations currently started
* @param nStopped number of remote stations currently stopped
*/
public void netReceiveStatus(long timeMilliseconds, int nPrepared, int nStarted, int nStopped) {
if (this.nNetStarted == 0 && nStarted >= 1) {
System.out.println("Starting \"processing\" Received network data");
this.pamStart(true, timeMilliseconds);
}
if (this.nNetStarted >= 1 && nStarted == 0) {
System.out.println("Stopping processing Received network data");
this.pamStop();
}
this.nNetPrepared = nPrepared;
this.nNetStarted = nStarted;
this.nNetStopped = nStopped;
}
/**
* Loop through all controllers and processes and datablocks and set up all of
* their annotations.
*/
private void createAnnotations() {
PamControlledUnit pcu;
PamProcess pp;
PamDataBlock pdb;
int nPcu, nPp, nPdb;
nPcu = getNumControlledUnits();
for (int iPcu = 0; iPcu < nPcu; iPcu++) {
pcu = getControlledUnit(iPcu);
nPp = pcu.getNumPamProcesses();
for (int iPp = 0; iPp < nPp; iPp++) {
pp = pcu.getPamProcess(iPp);
// only do top processes (ones which have no source datablock
if (pp.getSourceDataBlock() == null) {
pp.createAnnotations(true);
}
// nPdb = pp.getNumOutputDataBlocks();
// for (int iPdb = 0; iPdb < nPdb; iPdb++) {
// pdb = pp.getOutputDataBlock(iPdb);
// pdb.createAnnotations(pp.getSourceDataBlock(), pp);
// }
}
}
}
/**
* Organise the GUI frames on start up or after a module was added or after the
* frames menus have changed.
*/
private void organiseGUIFrames() {
}
// private void createViewerStatusBar() {
//
// viewerStatusBar = new ViewerStatusBar(this);
// PamStatusBar.getStatusBar().getToolBar().setLayout(new BorderLayout());
// PamStatusBar.getStatusBar().getToolBar().add(BorderLayout.CENTER,
// viewerStatusBar.getStatusBarComponent());
// }
void setupProcesses() {
// for (int i = 0; i < pamControlledUnits.size(); i++) {
// pamControlledUnits.get(i).setupControlledUnit();
// }
pamConfiguration.setupProcesses();
}
/**
* Can PAMGUARD shut down. This question is asked in turn to every module. Each
* module should attempt to make sure it can answer true, e.g. by closing files,
* but if any module returns false, then canClose() will return false;
*
* @return whether it's possible to close PAMGUARD without corrupting or losing
* data.
*/
public boolean canClose() {
return pamConfiguration.canClose();
}
/**
* Called after canClose has returned true to finally tell all modules that
* PAMGUARD is definitely closing down.so they can free any resources, etc.
*/
@Override
public void pamClose() {
getUidManager().runShutDownOps();
pamConfiguration.pamClose();
}
/**
* Shut down Pamguard
*/
public void shutDownPamguard() {
// force close the javaFX thread (because it won't close by itself - see
// Platform.setImplicitExit(false) in constructor
try {
Platform.exit();
}
catch (Exception e) {
System.out.println(e.getMessage());
}
// terminate the JVM
System.exit(getPamStatus());
}
/**
* Go through all data blocks in all modules and tell them to save. This has
* been built into PamProcess and PamDataBlock since we want it to be easy to
* override this for specific modules / processes / data blocks.
*/
public void saveViewerData() {
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
for (int i = 0; i < pamControlledUnits.size(); i++) {
pamControlledUnits.get(i).saveViewerData();
}
// Commit the database.
DBControlUnit dbControl = DBControlUnit.findDatabaseControl();
if (dbControl != null) {
dbControl.commitChanges();
}
}
@Override
public void addControlledUnit(PamControlledUnit controlledUnit) {
pamConfiguration.addControlledUnit(controlledUnit);
guiFrameManager.addControlledUnit(controlledUnit);
notifyModelChanged(PamControllerInterface.ADD_CONTROLLEDUNIT);
}
@Override
public PamControlledUnit addModule(Frame parentFrame, PamModuleInfo moduleInfo) {
// first of all we need to get a name for the new module
// String question = "Enter a name for the new " + moduleInfo.getDescription();
// String newName = JOptionPane.showInputDialog(null, question,
// "New " + moduleInfo.getDescription(), JOptionPane.OK_CANCEL_OPTION);
// String newName = NewModuleDialog.showDialog(parentFrame ,moduleInfo,null);
String newName = guiFrameManager.getModuleName(parentFrame, moduleInfo);
if (newName == null)
return null;
return addModule(moduleInfo, newName);
}
/**
* Add a module to the controller.
*
* @param moduleInfo - the module info i.e. the type of module to add
* @param moduleName - the module name.
* @return
*/
public PamControlledUnit addModule(PamModuleInfo moduleInfo, String moduleName) {
// Comment this section out and replace with code below, to provide custom error
// handling with PamExceptionHandler
// PamControlledUnit pcu = moduleInfo.create(moduleName);
// if (pcu == null) return null;
// addControlledUnit(pcu);
// if (initializationComplete) {
// pcu.setupControlledUnit();
// }
// return pcu;
// try to load the unit. If moduleInfo.create returns null, clear the name and
// exit. Otherwise, save
// the name of the module being loaded
unitBeingLoaded = moduleInfo.create(moduleName);
if (unitBeingLoaded == null) {
return null;
}
// try to add the unit to the list.
// Put this method call in a try/catch, in case the developer hasn't coded
// the plugin properly. We need to catch Throwable, not Exception, in order
// to catch everything (e.g. if one of the abstract methods is missing, java
// throws AbstractMethodError. This is an error, not an exception, so if
// we want to catch it we need to catch Throwable. Same with a
// ClassDefNotFoundError,
// in case the plugin is looking for a class in the Pamguard core that no longer
// exists).
// Also check if unitBeingLoaded=null afterwards because this would indicate
// that the PamExceptionHandler caught a runtime error during the class
// instantiation and therefore
// removed the module to prevent further errors. This could also happen due to
// incompatibilities between
// the current version of Pamguard and older plugin modules.
try {
addControlledUnit(unitBeingLoaded);
} catch (Throwable e) {
e.printStackTrace();
String title = "Error adding module";
String msg = "There is an error with the module " + moduleName + ".<p>"
+ "If this is a plug-in, the error may have been caused by an incompatibility between "
+ "it and this version of PAMGuard. Please check the developer's website " + "for help.<p>"
+ "If this is a core Pamguard module, please copy the error message text and email to"
+ "support@pamguard.org.<p>" + "This module will not be loaded.";
String help = null;
int ans = WarnOnce.showWarning(title, msg, WarnOnce.WARNING_MESSAGE, help, e);
System.err.println("Exception while loading " + moduleName);
//this.removeControlledUnt(unitBeingLoaded);
this.clearLoadedUnit();
}
if (unitBeingLoaded == null) {
return null;
}
// run the unit's setupProcess method. Again, check if nitBeingLoaded=null
// afterwards because this would indicate
// that the PamExceptionHandler caught a runtime error during the class
// instantiation and therefore
// removed the module to prevent further errors. This could happen due to
// incompatibilities between
// the current version of Pamguard and older plugin modules.
if (initializationComplete) {
unitBeingLoaded.setupControlledUnit();
}
if (unitBeingLoaded == null) {
return null;
}
// move the controlled unit reference to a temp variable, so that we can
// clear the unitBeingLoaded variable and still pass a reference to the
// new unit back to the calling function. In this way, we can always use
// the unitBeingLoaded variable as a de facto flag to know whether or not
// a module is currently being loaded
PamControlledUnit unitNowLoaded = unitBeingLoaded;
clearLoadedUnit();
// guiFrameManager.notifyModelChanged(ADD_CONTROLLEDUNIT); //this should be
// handled above in addControlledUnit
return unitNowLoaded;
}
/*
* (non-Javadoc)
*
* @see PamguardMVC.PamControllerInterface#RemoveControlledUnt(PamguardMVC.
* PamControlledUnit)
*/
@Override
public void removeControlledUnt(PamControlledUnit controlledUnit) {
// The PamExceptionHandler will call this to remove a controlled unit that fails
// during load. Depending when it failed, it may or may not have been
// instantiated
// yet. So if the controlledUnit is still null, just exit
//
if (controlledUnit == null) {
return;
}
/**
* NEVER delete the array manager.
*/
if (controlledUnit.getClass() == ArrayManager.class) {
return;
}
guiFrameManager.removeControlledUnit(controlledUnit);
boolean removed = pamConfiguration.removeControlledUnt(controlledUnit);
if (removed) {
notifyModelChanged(PamControllerInterface.REMOVE_CONTROLLEDUNIT);
}
// getMainFrame().revalidate(); //handled inside the GUIFrameManager by notify
// model changed. The controller should have
// as few direct GUI calls as possible.
}
/*
* (non-Javadoc)
*
* @see PamController.PamControllerInterface#orderModules()
*/
@Override
public boolean orderModules(Frame parentFrame) {
int[] newOrder = ModuleOrderDialog.showDialog(this, parentFrame);
if (newOrder != null) {
// re-order the modules according the new list.
pamConfiguration.reOrderModules(newOrder);
notifyModelChanged(PamControllerInterface.REORDER_CONTROLLEDUNITS);
return true;
}
return false;
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.