From a1adff82cb3f45f4b5a86593b7c6f1f08610b0b7 Mon Sep 17 00:00:00 2001 From: Jamie Mac Date: Thu, 18 Apr 2024 12:09:36 +0100 Subject: [PATCH] Updates to exporter and detection display in FX GUI --- .classpath | 2 +- .gitignore | 1 + .../filedate/FileDateDialogStrip.java | 8 +- src/Map/MapDetectionsDialog.java | 7 +- .../component/PamSettingsIconButton.java | 10 +- src/PamView/dialog/SettingsButton.java | 11 +- .../DetectionDisplayControl2.java | 6 +- .../DetectionGroupDisplay.java | 45 +++- .../DetectionGroupDisplayFX.java | 48 +++- src/detectionPlotFX/DetectionPlotParams.java | 16 +- src/detectionPlotFX/GroupDisplayListener.java | 2 +- src/detectionPlotFX/data/DDDataInfo.java | 211 ++++++++++-------- src/detectionPlotFX/layout/DDDataPane2.java | 1 - .../layout/DetectionPlotDisplay.java | 3 +- src/export/ExportOptions.java | 1 - src/export/MLExport/MLDetectionsManager.java | 55 ++++- src/export/PamDataUnitExporter.java | 3 +- src/export/PamExporterManager.java | 84 ++++++- src/export/RExport/RExportManager.java | 2 +- src/export/layoutFX/ExportParams.java | 6 +- src/export/swing/ExportProcessDialog.java | 19 +- src/export/swing/ExportTask.java | 40 +++- .../wavExport/WavFileExportManager.java | 2 +- src/offlineProcessing/OLProcessDialog.java | 8 +- src/pamViewFX/PAMGuiFXSettings.java | 2 +- .../panels/TargetMotionMainPanel.java | 10 +- 26 files changed, 442 insertions(+), 161 deletions(-) diff --git a/.classpath b/.classpath index 576b210a..c623317c 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,7 @@ - + diff --git a/.gitignore b/.gitignore index 4291307d..b916a1cd 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,4 @@ settings.xml .project .classpath .classpath +.classpath diff --git a/src/Acquisition/filedate/FileDateDialogStrip.java b/src/Acquisition/filedate/FileDateDialogStrip.java index 836850e6..fb97ab26 100644 --- a/src/Acquisition/filedate/FileDateDialogStrip.java +++ b/src/Acquisition/filedate/FileDateDialogStrip.java @@ -1,6 +1,7 @@ package Acquisition.filedate; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -15,6 +16,9 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + import PamUtils.PamCalendar; import PamView.dialog.PamGridBagContraints; @@ -35,7 +39,9 @@ public class FileDateDialogStrip { private JButton settingsButton; - private ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); +// private ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); + public static FontIcon settingsIcon = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); + private Window parent; diff --git a/src/Map/MapDetectionsDialog.java b/src/Map/MapDetectionsDialog.java index bb85bdb9..1a9b100b 100644 --- a/src/Map/MapDetectionsDialog.java +++ b/src/Map/MapDetectionsDialog.java @@ -1,6 +1,7 @@ package Map; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -16,6 +17,9 @@ import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.TitledBorder; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + import PamController.PamController; import PamView.dialog.PamDialog; import PamguardMVC.PamDataBlock; @@ -85,7 +89,8 @@ public class MapDetectionsDialog extends PamDialog { MapDetectionData md; - ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); +// ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); + FontIcon settingsIcon = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); for (int i = 0; i < n; i++) { md = mapDetectionsParameters.mapDetectionDatas.get(i); diff --git a/src/PamView/component/PamSettingsIconButton.java b/src/PamView/component/PamSettingsIconButton.java index 817903a5..20e6feda 100644 --- a/src/PamView/component/PamSettingsIconButton.java +++ b/src/PamView/component/PamSettingsIconButton.java @@ -1,8 +1,13 @@ package PamView.component; +import java.awt.Color; + import javax.swing.ImageIcon; import javax.swing.JButton; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + public class PamSettingsIconButton extends JButton { /** @@ -10,8 +15,9 @@ public class PamSettingsIconButton extends JButton { */ private static final long serialVersionUID = 1L; - private static final ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); - +// private static final ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); + private static final FontIcon settingsIcon = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); + /** * Create a simple square button using the given icon. */ diff --git a/src/PamView/dialog/SettingsButton.java b/src/PamView/dialog/SettingsButton.java index d3b029f4..510a1711 100644 --- a/src/PamView/dialog/SettingsButton.java +++ b/src/PamView/dialog/SettingsButton.java @@ -1,9 +1,15 @@ package PamView.dialog; +import java.awt.Color; + import javax.swing.Action; +import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + /** * Standard settings button with the little cogwheel for use throughout Swing components. * @author dg50 @@ -20,8 +26,9 @@ public class SettingsButton extends JButton { super(makeIcon()); } - private static ImageIcon makeIcon() { - return new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); + private static Icon makeIcon() { + return FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); +// return new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); } /** diff --git a/src/detectionPlotFX/DetectionDisplayControl2.java b/src/detectionPlotFX/DetectionDisplayControl2.java index b830f716..419f44ea 100644 --- a/src/detectionPlotFX/DetectionDisplayControl2.java +++ b/src/detectionPlotFX/DetectionDisplayControl2.java @@ -104,7 +104,7 @@ public class DetectionDisplayControl2 extends UserDisplayControlFX { */ public boolean newDataBlockAdded(PamDataBlock pamDataBlock){ - System.out.println("NEW DATA BLOCK DETECTION DISPLAY: " + pamDataBlock); + //System.out.println("NEW DATA BLOCK DETECTION DISPLAY: " + pamDataBlock); //if null then no parent- simply set the DDataInfo to null; if (pamDataBlock==null) { @@ -127,6 +127,8 @@ public class DetectionDisplayControl2 extends UserDisplayControlFX { //set the paramters. displays=new ArrayList(); displays.add(detectionDisplay); + //TODO +// detectionDisplay.setEnableScrollBar(false); //make this an option } return displays; } @@ -148,7 +150,7 @@ public class DetectionDisplayControl2 extends UserDisplayControlFX { @Override public void addData(PamObservable o, PamDataUnit arg) { - System.out.println("DetectionDisplay: INCOMING data unit: "+ arg); + //System.out.println("DetectionDisplay: INCOMING data unit: "+ arg); //send the data unit to the display. detectionDisplay.setDataUnit(arg); } diff --git a/src/detectionPlotFX/DetectionGroupDisplay.java b/src/detectionPlotFX/DetectionGroupDisplay.java index 293ba7aa..a1d45604 100644 --- a/src/detectionPlotFX/DetectionGroupDisplay.java +++ b/src/detectionPlotFX/DetectionGroupDisplay.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import PamController.PamSettingManager; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.superdet.SuperDetection; @@ -24,7 +23,6 @@ import javafx.scene.control.TabPane; import javafx.scene.control.TabPane.TabClosingPolicy; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Pane; -import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; import pamViewFX.PamGuiManagerFX; import pamViewFX.fxGlyphs.PamGlyphDude; @@ -33,19 +31,16 @@ import pamViewFX.fxNodes.PamButton; import pamViewFX.fxNodes.PamHBox; import pamViewFX.fxNodes.PamStackPane; import pamViewFX.fxNodes.hidingPane.HidingPane; -import pamViewFX.fxNodes.internalNode.PamInternalPane; import pamViewFX.fxStyles.PamStylesManagerFX; -import userDisplayFX.UserDisplayNodeFX; -import userDisplayFX.UserDisplayNodeParams; /** * - * A display which shows a list of data units with arrows allowing the user to - * navigate through the different data units. + * A detection plot display with convenience functions to set any type of data unit. * * @author Jamie Macaulay * */ +@SuppressWarnings("rawtypes") public class DetectionGroupDisplay extends PamBorderPane { public static final int DISPLAY_COMPACT = 0; @@ -368,14 +363,15 @@ public class DetectionGroupDisplay extends PamBorderPane { * Sets the current in the display. * @param pamDataUnit - the current data unit to set. * @param detectionDisplay- the detection display plot to set the data unit for. + * @return true of a new data info has been added - usually means a different type of detection to display compared to the last detection. */ - public void setDataUnit(PamDataUnit dataUnit){ + public boolean setDataUnit(PamDataUnit dataUnit){ detectionDisplay.clearPane(); if (dataUnit==null) { detectionDisplay.removeDataInfo(); - return; + return true; } // TDDataInfoFX dataInfo = this.tdGraphFX.findDataInfo(dataUnit); @@ -407,7 +403,7 @@ public class DetectionGroupDisplay extends PamBorderPane { dDataInfoHashMap.put(dataUnit.getParentDataBlock(), dDataInfo); } - if (dDataInfo==null) return; + if (dDataInfo==null) return true; //only change the dDataInfo if it's different,. boolean newDataInfo = false; @@ -435,6 +431,25 @@ public class DetectionGroupDisplay extends PamBorderPane { // clearSingleType(); //TODO....highlight data unit. + + return newDataInfo; + } + + + /** + * Attempts to set the detectionPlot + * @param plotName + * @return + */ + public boolean setDetectionPlot(String plotName) { + + //set the current detection plot based in the name + boolean setOk = currentDataInfo.setCurrentDetectionPlot(plotName); + + //update the detection settings pane so it shows the correct plot names etc. + detectionDisplay.getDataTypePane().notifyDataChange(); + + return setOk; } @@ -445,7 +460,7 @@ public class DetectionGroupDisplay extends PamBorderPane { */ public void triggerListeners(PamDataUnit oldDataUnit, PamDataUnit newDataUnit) { for (GroupDisplayListener aListener : displayListeners) { - aListener.newDataUnitSlected(oldDataUnit, newDataUnit); + aListener.newDataUnitSelected(oldDataUnit, newDataUnit); } } @@ -497,6 +512,14 @@ public class DetectionGroupDisplay extends PamBorderPane { return detectionGroup.get(currentUnitIndex); } + + /** + * Show the scroll bar which allows the user to chnage time limits. + * @param enableScrollBarPane - true to enable the time scroll bar. + */ + public void setEnableScrollBar(boolean enableScrollBarPane) { + this.detectionDisplay.setEnableScrollBar(enableScrollBarPane); + } diff --git a/src/detectionPlotFX/DetectionGroupDisplayFX.java b/src/detectionPlotFX/DetectionGroupDisplayFX.java index afad5414..0cbe85a0 100644 --- a/src/detectionPlotFX/DetectionGroupDisplayFX.java +++ b/src/detectionPlotFX/DetectionGroupDisplayFX.java @@ -7,6 +7,7 @@ import PamController.PamController; import PamController.PamSettingManager; import PamController.PamSettings; import PamguardMVC.PamDataBlock; +import PamguardMVC.PamDataUnit; import javafx.geometry.Side; import javafx.scene.layout.Region; import pamViewFX.fxNodes.internalNode.PamInternalPane; @@ -29,7 +30,9 @@ public class DetectionGroupDisplayFX extends DetectionGroupDisplay implements U */ private PamInternalPane internalFrame; - private DetectionDisplayControl2 displayControl; + private DetectionDisplayControl2 displayControl; + + private PamDataUnit currentDetection; public DetectionGroupDisplayFX(DetectionDisplayControl2 displayControl){ super(DetectionGroupDisplay.DISPLAY_COMPACT); @@ -152,9 +155,9 @@ public class DetectionGroupDisplayFX extends DetectionGroupDisplay implements U prepareDisplayParams(); detectionPlotParams = getDisplayParams(); - System.out.println("SAVE DETECTION DISPLAY DATA SOURCE: " + detectionPlotParams.dataSource); - System.out.println("SAVE DETECTION DISPLAY TAB NAME: " + detectionPlotParams.tabName); - +// System.out.println("SAVE DETECTION DISPLAY DATA SOURCE: " + detectionPlotParams.dataSource); +// System.out.println("SAVE DETECTION DISPLAY TAB NAME: " + detectionPlotParams.tabName); + return detectionPlotParams; } @@ -182,9 +185,8 @@ public class DetectionGroupDisplayFX extends DetectionGroupDisplay implements U return false; } - System.out.println("LOAD DETECTION DISPLAY DATA SOURCE: " + settings.dataSource); - System.out.println("LOAD DETECTION DISPLAY DATA SOURCE: " + settings.tabName); - +// System.out.println("LOAD DETECTION DISPLAY DATA SOURCE: " + settings.dataSource); +// System.out.println("LOAD DETECTION DISPLAY DATA SOURCE: " + settings.tabName); this.detectionPlotParams = settings.clone(); return true; @@ -204,5 +206,37 @@ public class DetectionGroupDisplayFX extends DetectionGroupDisplay implements U public UserDisplayControlFX getUserDisplayControl() { return displayControl; } + + @Override + public boolean setDataUnit(PamDataUnit dataUnit){ + + /** + * The extra stuff here is to make sure that the plot types for a specific detectin are saved. So for example + * if viewing click spectrum then the spectrum plot is selected whenever 1) PAMGuard is opned again or 2) switching from + * one type of detection ot another e.g. whistle to click, then the click does nto revert to shwoing a waveform instead + * of spectrum. + */ + + if (currentDetection!=null) { + //save the current selected detection plot for the particular type of data unit. + String detectionPlotName = this.getDetectionDisplay().getCurrentDataInfo().getCurrentDetectionPlot().getName(); +// System.out.println("SET CURRENT DETECTION PLOT TO USE IS: " + detectionPlotName); + detectionPlotParams.dataAxisMap.put(currentDetection.getParentDataBlock().getLongDataName(), detectionPlotName); + } + + this.currentDetection = dataUnit; + + //setup the new data unit + boolean newDataInfo = super.setDataUnit(dataUnit); + + if (newDataInfo && dataUnit!=null) { + //if there's a new data info we may want to set the detection back to it's most recent selection + String detectionPlotName = detectionPlotParams.dataAxisMap.get(dataUnit.getParentDataBlock().getLongDataName()); +// System.out.println("THE CURRENT DETECTION PLOT TO USE IS: " + detectionPlotName); + setDetectionPlot(detectionPlotName); + } + + return newDataInfo; + } } diff --git a/src/detectionPlotFX/DetectionPlotParams.java b/src/detectionPlotFX/DetectionPlotParams.java index d05ac47a..67bf3a85 100644 --- a/src/detectionPlotFX/DetectionPlotParams.java +++ b/src/detectionPlotFX/DetectionPlotParams.java @@ -1,5 +1,7 @@ package detectionPlotFX; +import java.util.HashMap; + import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PamParameterSet.ParameterSetType; @@ -13,17 +15,25 @@ import userDisplayFX.UserDisplayNodeParams; * */ public class DetectionPlotParams extends UserDisplayNodeParams implements Cloneable, ManagedParameters { + + + /** + * + */ + static final long serialVersionUID = 2L; /** * The data source for the detection plot. */ public String dataSource = null; - + /** - * + * Saves which data axis is used for which data block. The key is the data block long name and the + * result is the name of the plot e.g. waveform. In this way users can set how they want the data plots to display + * different types of data units and the dispay types are saved on PAMGuard opne and close. */ - static final long serialVersionUID = 1L; + public HashMap dataAxisMap = new HashMap(); /* (non-Javadoc) diff --git a/src/detectionPlotFX/GroupDisplayListener.java b/src/detectionPlotFX/GroupDisplayListener.java index 2f4f5e55..1f1483c1 100644 --- a/src/detectionPlotFX/GroupDisplayListener.java +++ b/src/detectionPlotFX/GroupDisplayListener.java @@ -16,5 +16,5 @@ public interface GroupDisplayListener { * @param oldDataUnit - the old data unit. * @param newDataUnit - the new selected data unit. */ - public void newDataUnitSlected(PamDataUnit oldDataUnit, PamDataUnit newDataUnit); + public void newDataUnitSelected(PamDataUnit oldDataUnit, PamDataUnit newDataUnit); } diff --git a/src/detectionPlotFX/data/DDDataInfo.java b/src/detectionPlotFX/data/DDDataInfo.java index 5fe4a66f..01c59f79 100644 --- a/src/detectionPlotFX/data/DDDataInfo.java +++ b/src/detectionPlotFX/data/DDDataInfo.java @@ -2,7 +2,6 @@ package detectionPlotFX.data; import java.util.ArrayList; import PamController.PamController; -import PamDetection.PamDetection; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import detectionPlotFX.DDScaleInfo; @@ -12,7 +11,6 @@ import detectionPlotFX.projector.DetectionPlotProjector; import javafx.scene.canvas.GraphicsContext; import javafx.scene.shape.Rectangle; import pamViewFX.fxNodes.PamBorderPane; -import pamViewFX.fxNodes.pamAxis.PamAxisFX; import pamViewFX.fxNodes.pamAxis.PamAxisPane2; /** @@ -23,23 +21,23 @@ import pamViewFX.fxNodes.pamAxis.PamAxisPane2; * */ public abstract class DDDataInfo { - - + + /** * Reference to the detection display plot */ private DetectionPlotDisplay dDPlot; - + /** * Pane whihc holds plot specifc settings. */ private PamBorderPane settingsPane= new PamBorderPane(); - + /** * The data block which the DDDataInfo is associated with */ private PamDataBlock pamDataBlock; - + /** * The scale information. Holds the min and max values for the x and y axis. */ @@ -49,12 +47,12 @@ public abstract class DDDataInfo { * True if in viewer mode. */ private boolean isViewer=false; - + /** * List of detection plots which can display the data unit. */ private ArrayList detectionPlots; - + /* * The index of the current detection plot */ @@ -64,23 +62,23 @@ public abstract class DDDataInfo { * The sample rate */ private float hardSampleRate=-1; - -// /** -// * Create the DDDataInfo -// * @param dDDataProvider - the data provider -// * @param dDPlot - the detection plot -// * @param pamDataBlock - the parent datablock -// */ -// public DDDataInfo(DetectionPlotDisplay dDPlot, PamDataBlock pamDataBlock) { -// super(); -// this.dDPlot=dDPlot; -// this.pamDataBlock = pamDataBlock; -// this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); -// detectionPlots=new ArrayList(); -// } - - + + // /** + // * Create the DDDataInfo + // * @param dDDataProvider - the data provider + // * @param dDPlot - the detection plot + // * @param pamDataBlock - the parent datablock + // */ + // public DDDataInfo(DetectionPlotDisplay dDPlot, PamDataBlock pamDataBlock) { + // super(); + // this.dDPlot=dDPlot; + // this.pamDataBlock = pamDataBlock; + // this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); + // detectionPlots=new ArrayList(); + // } + + /** * Create the DDDataInfo * @param dDDataProvider - the dataplot provider @@ -94,7 +92,7 @@ public abstract class DDDataInfo { this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); detectionPlots=new ArrayList(); } - + /** * Create the DDdata info wothout reference to a provider * @param dDPlot - - the data plot @@ -107,20 +105,20 @@ public abstract class DDDataInfo { this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); detectionPlots=new ArrayList(); } - -// /** -// * Create the DDdata info wothout reference to a provider -// * @param dDPlot - - the data plot -// * @param pamDataBlock - the parent datablopck -// */ -// public DDDataInfo(DetectionPlotDisplay dDPlot, float sR) { -// super(); -// this.dDPlot=dDPlot; -// this.hardSampleRate=sR; -// this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); -// detectionPlots=new ArrayList(); -// } - + + // /** + // * Create the DDdata info wothout reference to a provider + // * @param dDPlot - - the data plot + // * @param pamDataBlock - the parent datablopck + // */ + // public DDDataInfo(DetectionPlotDisplay dDPlot, float sR) { + // super(); + // this.dDPlot=dDPlot; + // this.hardSampleRate=sR; + // this.isViewer = (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW); + // detectionPlots=new ArrayList(); + // } + /** * Get the data block for this information * @return the datablock. This can be null. @@ -128,8 +126,8 @@ public abstract class DDDataInfo { public PamDataBlock getDataBlock() { return pamDataBlock; } - - + + /** * Get the sample rate. This is acquired form the datablock if one exists. Otherwise a hard * wired sample rate is used. @@ -139,9 +137,9 @@ public abstract class DDDataInfo { if (pamDataBlock!=null) return pamDataBlock.getSampleRate(); else return hardSampleRate; } - - - + + + /** * Set the sample rate. This is only used if the parent data block is null. * @return the sample rate. @@ -149,7 +147,7 @@ public abstract class DDDataInfo { public void setHardSampleRate(float hardSampleRate) { this.hardSampleRate = hardSampleRate; } - + /** * Add a type of data unit to the list. * @param unitType String name of the data unit. @@ -157,7 +155,7 @@ public abstract class DDDataInfo { public void addDetectionPlot(DetectionPlot detectionPlot) { detectionPlots.add(detectionPlot); } - + /** * Get a detection plot * @param the index of the detection plot to get. @@ -165,14 +163,14 @@ public abstract class DDDataInfo { public DetectionPlot getDetectionPlot(int i) { return detectionPlots.get(i); } - + /** * The number of possible detection plots for the data unit. */ public int getDetectionPlotCount(){ return detectionPlots.size(); } - + /** * Get the scale information. This holds the min and max values for the x and y axis along with other * axis related parameters. @@ -188,42 +186,57 @@ public abstract class DDDataInfo { public DetectionPlotDisplay getDetectionPlotDisplay() { return dDPlot; } - + /* * Sets the current detection plot to be shown. * @param index of the plot in the plot list. */ public void setCurrentDetectionPlot(int index) { - this.currentDetectionPlotIndex=index; - if (index>=0 && index=0 && index { if (currentDetectionPlotIndex<0 || currentDetectionPlotIndex>=detectionPlots.size()) return null; return detectionPlots.get(currentDetectionPlotIndex); } - - + + /** * Get the settings pane for this DDDataInfo. This holds plot specific settings. * @return @@ -243,7 +256,7 @@ public abstract class DDDataInfo { public PamBorderPane getSettingsPane(){ return settingsPane; } - + /** * Paint data into the graphics window. @@ -255,17 +268,17 @@ public abstract class DDDataInfo { * @param a flag with extra information - e.g. if this is a scroll bar paint or not. */ public void drawData(GraphicsContext g, Rectangle windowRect, DetectionPlotProjector projector, T pamDataUnit, int flag){ - + if (getCurrentDetectionPlot()==null) return; - + g.clearRect(0, 0, windowRect.getWidth(), windowRect.getHeight()); - + getCurrentDetectionPlot().setupAxis((PamDataUnit) pamDataUnit, this.getHardSampleRate(), projector); - + getCurrentDetectionPlot().paintPlot((PamDataUnit) pamDataUnit, g, windowRect, projector, flag); - + } - + /** * Paint data into the graphics window. @@ -276,8 +289,8 @@ public abstract class DDDataInfo { * @param newDataUnit - the data unit to plot. */ public void drawData(GraphicsContext g, Rectangle windowRect, DetectionPlotProjector projector, T pamDataUnit){ - - drawData( g, windowRect, projector, pamDataUnit, DetectionPlot.STANDARD_DRAW); + + drawData( g, windowRect, projector, pamDataUnit, DetectionPlot.STANDARD_DRAW); } @@ -286,23 +299,23 @@ public abstract class DDDataInfo { getCurrentDetectionPlot().setupAxis((PamDataUnit) pamDataUnit, this.getHardSampleRate(), projector); } -// /** -// * Gets a value for a specific data unit which should be in the -// * same units as the scale information. This will then be -// * converted into a plot position by the TDGraph. -// * @param pamDataUnit -// * @return data value or null if this data point should not be plotted. -// */ -// abstract public Double[] getYValue(PamDataUnit pamDataUnit); -// -// /** -// * Gets a value for a specific data unit which should be in the -// * same units as the scale information. This will then be -// * converted into a plot position by the TDGraph. -// * @param pamDataUnit -// * @return data value or null if this data point should not be plotted. -// */ -// abstract public Double[] getXValue(PamDataUnit pamDataUnit); - + // /** + // * Gets a value for a specific data unit which should be in the + // * same units as the scale information. This will then be + // * converted into a plot position by the TDGraph. + // * @param pamDataUnit + // * @return data value or null if this data point should not be plotted. + // */ + // abstract public Double[] getYValue(PamDataUnit pamDataUnit); + // + // /** + // * Gets a value for a specific data unit which should be in the + // * same units as the scale information. This will then be + // * converted into a plot position by the TDGraph. + // * @param pamDataUnit + // * @return data value or null if this data point should not be plotted. + // */ + // abstract public Double[] getXValue(PamDataUnit pamDataUnit); + } diff --git a/src/detectionPlotFX/layout/DDDataPane2.java b/src/detectionPlotFX/layout/DDDataPane2.java index b754f1cb..240a54f3 100644 --- a/src/detectionPlotFX/layout/DDDataPane2.java +++ b/src/detectionPlotFX/layout/DDDataPane2.java @@ -87,7 +87,6 @@ public class DDDataPane2 extends PamBorderPane { dataPlots.getItems().add(ddDataInfo.getDetectionPlot(i).getName()); - if (ddDataInfo.getCurrentDetectionPlot()==ddDataInfo.getDetectionPlot(i)) { index=i; } diff --git a/src/detectionPlotFX/layout/DetectionPlotDisplay.java b/src/detectionPlotFX/layout/DetectionPlotDisplay.java index 9652ddcb..439301e9 100644 --- a/src/detectionPlotFX/layout/DetectionPlotDisplay.java +++ b/src/detectionPlotFX/layout/DetectionPlotDisplay.java @@ -73,8 +73,7 @@ public class DetectionPlotDisplay extends PamBorderPane { /** * Pane which sits on the right hand side and */ - private PamBorderPane settingsHolder; - + private PamBorderPane settingsHolder; /** diff --git a/src/export/ExportOptions.java b/src/export/ExportOptions.java index a78e2da5..0ce6a1f8 100644 --- a/src/export/ExportOptions.java +++ b/src/export/ExportOptions.java @@ -57,7 +57,6 @@ public class ExportOptions implements PamSettings { if (exportProcessDialog==null) { exportProcessDialog= new ExportProcessDialog(exportManager); } - this.exportProcessDialog.showOfflineDialog(parentFrame, this.storageParameters); // ExportParams newParams = StorageOptionsDialog.showDialog(parentFrame, storageParameters); diff --git a/src/export/MLExport/MLDetectionsManager.java b/src/export/MLExport/MLDetectionsManager.java index 38c14cca..37f20911 100644 --- a/src/export/MLExport/MLDetectionsManager.java +++ b/src/export/MLExport/MLDetectionsManager.java @@ -1,13 +1,19 @@ package export.MLExport; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import PamguardMVC.PamDataUnit; import export.PamDataUnitExporter; import us.hebi.matlab.mat.format.Mat5; +import us.hebi.matlab.mat.format.Mat5File; +import us.hebi.matlab.mat.types.Matrix; +import us.hebi.matlab.mat.types.Sink; +import us.hebi.matlab.mat.types.Sinks; import us.hebi.matlab.mat.types.Struct; +import us.hebi.matlab.mat.util.Casts; /** @@ -47,7 +53,21 @@ public class MLDetectionsManager implements PamDataUnitExporter { } @Override - public boolean exportData(File fileName, List dataUnits) { + public boolean exportData(File fileName, List dataUnits, boolean append) { + + + try { + Mat5File matFile = Mat5.newMatFile(); + Sink sink = Sinks.newMappedFile(fileName, Casts.sint32(1000000)); + + matFile.writeTo(sink);//Streams the data into a MAT file? + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + return false; } @@ -141,6 +161,39 @@ public class MLDetectionsManager implements PamDataUnitExporter { public String getName() { return "MATLAB"; } + + public static void main(String args[]) { + + String fileName = "/Users/au671271/MATLAB-Drive/MATLAB/PAMGUARD/_test/export_test.mat"; + + try { + Mat5File matFile = Mat5.newMatFile(); + + + Struct mlStruct = Mat5.newStruct(3, 1); + Matrix triggerMap = Mat5.newScalar(Math.random()); + + mlStruct.set("triggerMap", 0, triggerMap); + mlStruct.set("triggerMap", 1, triggerMap); + mlStruct.set("triggerMap", 2, triggerMap); + + matFile.addArray("test_struct", mlStruct); + + //basic method to write to a file + Mat5.writeToFile(matFile, fileName); + + +// Sink sink = Sinks.newMappedFile(new File(fileName), Casts.sint32(1000000)); +// +// matFile.writeTo(sink); +// +// sink.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } diff --git a/src/export/PamDataUnitExporter.java b/src/export/PamDataUnitExporter.java index 22c3dc2d..44c10599 100644 --- a/src/export/PamDataUnitExporter.java +++ b/src/export/PamDataUnitExporter.java @@ -23,9 +23,10 @@ public interface PamDataUnitExporter { * @param fileName - the file to export to * @param prefix - file prefix for filenames. * @param dataUnits - the data units to export. + * @param true to append the data to the current file - otherwise a new file is written. * @return true if exported successfully. */ - public boolean exportData(File fileName, List dataUnits); + public boolean exportData(File fileName, List dataUnits, boolean append); /** * Get the extension for the output file type diff --git a/src/export/PamExporterManager.java b/src/export/PamExporterManager.java index 7a9fd4e0..f81a50f9 100644 --- a/src/export/PamExporterManager.java +++ b/src/export/PamExporterManager.java @@ -1,11 +1,14 @@ package export; +import java.io.File; import java.util.ArrayList; +import PamUtils.PamCalendar; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import export.MLExport.MLDetectionsManager; import export.RExport.RExportManager; +import export.layoutFX.ExportParams; import export.wavExport.WavFileExportManager; /** @@ -13,37 +16,96 @@ import export.wavExport.WavFileExportManager; * offline processing. */ public class PamExporterManager { - + + /** + * The number of data units to save before saving. + */ + private static int BUFFER_SIZE = 1000; + + /** + * Keep the file size to around 1GB per file + */ + private static int MAX_FILE_SIZE_MB = 1024; + + + /** + * A buffer of data units so we are not opening a file everytime a new data is passed to the export. + */ + private ArrayList dataUnitBuffer = new ArrayList(); + /** * A list of the avilable exporters. */ private ArrayList pamExporters; - - + + /** + * The current file. + */ + private File currentFile; + + /** + * Reference to the current export paramters. + */ + private ExportParams exportParams = new ExportParams(); + public PamExporterManager() { pamExporters = new ArrayList(); - + //add the MATLAB export pamExporters.add(new MLDetectionsManager()); pamExporters.add(new RExportManager()); pamExporters.add(new WavFileExportManager()); - - } /** * Add a data unit to the export list. */ - public void exportDataUnit(PamDataUnit dataUnit) { - // TODO Auto-generated method stub + public boolean exportDataUnit(PamDataUnit dataUnit) { + boolean exportOK = true; + //if the data unit is null then save everything to the buffer. + + if (currentFile == null || isFileSizeMax(currentFile)) { + //create a new file - note each exporter is responsible for closing the file after writing + //so previous files should already be closed + String fileName = (exportParams.folder + File.separator + PamCalendar.formatDate2(dataUnit.getTimeMilliseconds(), false) + + "." + pamExporters.get(exportParams.exportChoice).getFileExtension()); + + currentFile = new File(fileName); + } + + dataUnitBuffer.add(dataUnit); + + if (BUFFER_SIZE>=BUFFER_SIZE) { + exportOK = pamExporters.get(exportParams.exportChoice).exportData(currentFile, dataUnitBuffer, true); + dataUnitBuffer.clear(); + } + return exportOK; + + } + + /** + * Check whether the current file is greater than the maximum allowed file size. + * @param currentFile2 - the current file + * @return true of greater than or equal to the maximum file size. + */ + private boolean isFileSizeMax(File currentFile2) { + return getFileSizeMegaBytes(currentFile2) >= MAX_FILE_SIZE_MB; + } + + /** + * Get the file size in MegaBytes + * @param file + * @return + */ + private static double getFileSizeMegaBytes(File file) { + return (double) file.length() / (1024 * 1024); } - public boolean canExportDataBlock(PamDataBlock dataBlock) { for (PamDataUnitExporter exporter:pamExporters) { if (exporter.hasCompatibleUnits(dataBlock.getUnitClass())) return true; } - + return false; } @@ -62,7 +124,7 @@ public class PamExporterManager { */ public PamDataUnitExporter getExporter(int i) { return pamExporters.get(i); - + } diff --git a/src/export/RExport/RExportManager.java b/src/export/RExport/RExportManager.java index af5d0020..5ba0381d 100644 --- a/src/export/RExport/RExportManager.java +++ b/src/export/RExport/RExportManager.java @@ -137,7 +137,7 @@ public class RExportManager implements PamDataUnitExporter { @Override - public boolean exportData(File fileName, List dataUnits) { + public boolean exportData(File fileName, List dataUnits, boolean append) { // TODO Auto-generated method stub return false; } diff --git a/src/export/layoutFX/ExportParams.java b/src/export/layoutFX/ExportParams.java index c4db163d..aa68d5fe 100644 --- a/src/export/layoutFX/ExportParams.java +++ b/src/export/layoutFX/ExportParams.java @@ -16,10 +16,14 @@ public class ExportParams implements Serializable, Cloneable { private static final long serialVersionUID = 1L; /** - * The index of the ex;port choice. + * The index of the export choice. */ public int exportChoice = 0; + /** + * The folder to save to. + */ + public String folder = System.getProperty("user.home"); @Override public ExportParams clone() { diff --git a/src/export/swing/ExportProcessDialog.java b/src/export/swing/ExportProcessDialog.java index 554b22a3..c3721a23 100644 --- a/src/export/swing/ExportProcessDialog.java +++ b/src/export/swing/ExportProcessDialog.java @@ -140,6 +140,12 @@ public class ExportProcessDialog { */ private JSpinner spinner; + private ButtonGroup buttonGroup; + + /** + * A list of the export buttons so they are easy to select. + */ + private JToggleButton[] exportButtons; public ExportOLDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) { @@ -150,24 +156,30 @@ public class ExportProcessDialog { mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS)); mainPanel.setBorder(new TitledBorder("Export Settings")); - ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup = new ButtonGroup(); PamPanel buttonPanel = new PamPanel(); + ActionListener listener = actionEvent -> { System.out.println(actionEvent.getActionCommand() + " Selected"); + //TODO set the buttons to be disabled or enabled. + }; + exportButtons = new JToggleButton[exportManager.getNumExporters()]; for (int i = 0; i < exportManager.getNumExporters(); i++) { JToggleButton b = new JToggleButton(); b.setToolTipText("Export to " + exportManager.getExporter(i).getName() + " file (" + exportManager.getExporter(i).getFileExtension() + ")"); FontIcon icon = FontIcon.of(getIconFromString(exportManager.getExporter(i).getIconString())); icon.setIconSize(25); - icon.setIconColor(Color.GRAY); + icon.setIconColor(Color.DARK_GRAY); b.setIcon(icon); b.addActionListener(listener); + + exportButtons[i]=b; buttonGroup.add(b); buttonPanel.add(b); } @@ -267,12 +279,13 @@ public class ExportProcessDialog { return super.getParams(); } - public void setParams(ExportParams params) { if (params ==null) currentParams = new ExportParams(); currentParams = params.clone(); + buttonGroup.clearSelection(); + exportButtons[params.exportChoice].setSelected(true); } } diff --git a/src/export/swing/ExportTask.java b/src/export/swing/ExportTask.java index 0b9fa7db..a3582eb2 100644 --- a/src/export/swing/ExportTask.java +++ b/src/export/swing/ExportTask.java @@ -1,7 +1,10 @@ package export.swing; +import PamController.PamController; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; +import PamguardMVC.dataSelector.DataSelectDialog; +import PamguardMVC.dataSelector.DataSelector; import dataMap.OfflineDataMapPoint; import export.PamExporterManager; import offlineProcessing.OfflineTask; @@ -14,12 +17,21 @@ import offlineProcessing.OfflineTask; */ public class ExportTask extends OfflineTask>{ - PamExporterManager exporter; + /** + * Reference to the data exporter which manages exporting of data. + */ + private PamExporterManager exporter; + + /** + * The data selector for the data block + */ + private DataSelector dataSelector; public ExportTask(PamDataBlock> parentDataBlock, PamExporterManager exporter) { super(parentDataBlock); this.exporter = exporter; - // TODO Auto-generated constructor stub + dataSelector=parentDataBlock.getDataSelectCreator().getDataSelector(this.getUnitName() +"_clicks", false, null); + } @Override @@ -41,7 +53,29 @@ public class ExportTask extends OfflineTask>{ @Override public void loadedDataComplete() { - // TODO Auto-generated method stub + //force the exporter so save any remaning data units in the buffer + exporter.exportDataUnit(null); + + } + /** + * task has settings which can be called + * @return true or false + */ + public boolean hasSettings() { + return dataSelector!=null; + } + + /** + * Call any task specific settings + * @return true if settings may have changed. + */ + public boolean callSettings() { + + dataSelector.getDialogPanel().setParams(); + + DataSelectDialog dataSelectDialog = new DataSelectDialog(PamController.getMainFrame(), + this.getDataBlock(), dataSelector, null); + return dataSelectDialog.showDialog(); } diff --git a/src/export/wavExport/WavFileExportManager.java b/src/export/wavExport/WavFileExportManager.java index 000a8f5a..c830f826 100644 --- a/src/export/wavExport/WavFileExportManager.java +++ b/src/export/wavExport/WavFileExportManager.java @@ -431,7 +431,7 @@ public class WavFileExportManager implements PamDataUnitExporter { @Override public boolean exportData(File fileName, - List dataUnits) { + List dataUnits, boolean append) { // TODO Auto-generated method stub return false; } diff --git a/src/offlineProcessing/OLProcessDialog.java b/src/offlineProcessing/OLProcessDialog.java index 9e6f6c8a..bc94e2e1 100644 --- a/src/offlineProcessing/OLProcessDialog.java +++ b/src/offlineProcessing/OLProcessDialog.java @@ -1,6 +1,7 @@ package offlineProcessing; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -24,6 +25,9 @@ import javax.swing.SwingConstants; import javax.swing.WindowConstants; import javax.swing.border.TitledBorder; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + import PamUtils.PamCalendar; import PamUtils.TxtFileUtils; import PamView.CancelObserver; @@ -90,7 +94,9 @@ public class OLProcessDialog extends PamDialog { private PamPanel timeChunkDataPanel; - public static ImageIcon settings = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); +// public static ImageIcon settings = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png")); + public static FontIcon settings = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); + TaskStatus currentStatus = TaskStatus.IDLE; diff --git a/src/pamViewFX/PAMGuiFXSettings.java b/src/pamViewFX/PAMGuiFXSettings.java index 8a5af7a9..fed74564 100644 --- a/src/pamViewFX/PAMGuiFXSettings.java +++ b/src/pamViewFX/PAMGuiFXSettings.java @@ -36,7 +36,7 @@ public class PAMGuiFXSettings implements Serializable, Cloneable { /** * True if PG is in fullscreen on startup */ - public boolean fullscreen = true; + public boolean fullscreen = false; /* (non-Javadoc) diff --git a/src/targetMotionModule/panels/TargetMotionMainPanel.java b/src/targetMotionModule/panels/TargetMotionMainPanel.java index 1751961a..acfd1432 100644 --- a/src/targetMotionModule/panels/TargetMotionMainPanel.java +++ b/src/targetMotionModule/panels/TargetMotionMainPanel.java @@ -1,6 +1,7 @@ package targetMotionModule.panels; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Frame; @@ -13,7 +14,6 @@ import java.util.ArrayList; import java.util.Arrays; import javax.swing.ButtonGroup; -import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; @@ -24,6 +24,9 @@ import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.border.TitledBorder; +import org.kordamp.ikonli.materialdesign2.MaterialDesignC; +import org.kordamp.ikonli.swing.FontIcon; + import targetMotionModule.TargetMotionControl; import targetMotionModule.TargetMotionInformation; import targetMotionModule.TargetMotionLocaliser; @@ -74,8 +77,9 @@ public class TargetMotionMainPanel implements PamTabPanel public JTextField comment; private PamPanel southPanel; - public ImageIcon settings = new ImageIcon(ClassLoader - .getSystemResource("Resources/SettingsButtonSmall2.png")); +// public ImageIcon settings = new ImageIcon(ClassLoader +// .getSystemResource("Resources/SettingsButtonSmall2.png")); + public static FontIcon settings = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY); public TargetMotionMainPanel(TargetMotionLocaliser targetMotionLocaliser) {