Updates to exporter

Getting export capability working in PAMGuard
Updated POM to use more up to date repository
This commit is contained in:
Jamie Mac 2024-05-24 11:30:01 +01:00
parent 7df04d58a2
commit bf20889743
20 changed files with 555 additions and 113 deletions

View File

@ -6,9 +6,8 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-21.0.2.13-hotspot">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -1,5 +1,6 @@
eclipse.preferences.version=1
encoding//src/rawDeepLearningClassifer/segmenter/SegmenterProcess.java=UTF-8
encoding//src/test=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8
encoding/src=UTF-8

View File

@ -1,9 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=18
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=18
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -13,4 +13,4 @@ org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=18
org.eclipse.jdt.core.compiler.source=21

14
pom.xml
View File

@ -270,14 +270,12 @@
</repository>-->
<!-- Repo for Renjin Script Engine -->
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>bedatadriven</id>
<name>bedatadriven_renjin</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
</repository>
<repository>
<id>bedatadriven</id>
<name>bedatadriven public repo</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
</repository>
<repository>
<snapshots>

View File

@ -100,6 +100,7 @@ import PamguardMVC.uid.UIDManager;
import PamguardMVC.uid.UIDOnlineManager;
import PamguardMVC.uid.UIDViewerManager;
import binaryFileStorage.BinaryStore;
import export.ExportOptions;
import PamguardMVC.debug.Debug;
/**
@ -2692,13 +2693,23 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
* Respond to storage options dialog. Selects whethere data
* Respond to storage options dialog. Selects whether data
* are stored in binary, database or both
* @param parentFrame
*/
public void storageOptions(JFrame parentFrame) {
StorageOptions.getInstance().showDialog(parentFrame);
}
/**
* Show export options tp export data to other formats
* @param parentFrame
*/
public void exportData(JFrame parentFrame) {
ExportOptions.getInstance().showDialog(parentFrame);
}
/**
* Return a verbose level for debug output
@ -2941,4 +2952,6 @@ public class PamController implements PamControllerInterface, PamSettings {
return pamConfiguration;
}
}

View File

@ -1,13 +1,17 @@
package PamView;
import java.awt.Component;
import java.awt.Container;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Map;
import java.util.WeakHashMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
/**
@ -19,21 +23,51 @@ public class PamAWTUtils {
/**
* Disable an entire swing panel including all child components.
* @param panel - the panel to disable
* @param jComponent - the panel to disable
* @param isEnabled true if enabled.
*/
public static void setPanelEnabled(JPanel panel, Boolean isEnabled) {
panel.setEnabled(isEnabled);
Component[] components = panel.getComponents();
for (Component component : components) {
if (component instanceof JPanel) {
setPanelEnabled((JPanel) component, isEnabled);
}
component.setEnabled(isEnabled);
}
public static void setPanelEnabled(JComponent jComponent, Boolean isEnabled) {
setPanelEnabled(jComponent, isEnabled? 1 :-1);
}
// private static final Map<Component, Integer> componentAvailability = new WeakHashMap<Component, Integer>();
public static void setMoreEnabled(Component component) {
setPanelEnabled(component, +1);
}
public static void setMoreDisabled(Component component) {
setPanelEnabled(component, -1);
}
// val = 1 for enabling, val = -1 for disabling
private static void setPanelEnabled(Component component, int val) {
if (component != null) {
// final Integer oldValObj = componentAvailability.get(component);
//
// final int oldVal = (oldValObj == null)
// ? 0
// : oldValObj;
//
// final int newVal = oldVal + val;
// componentAvailability.put(component, newVal);
int newVal = val;
if (newVal >= 0) {
component.setEnabled(true);
} else if (newVal < 0) {
component.setEnabled(false);
}
if (component instanceof Container) {
Container componentAsContainer = (Container) component;
for (Component c : componentAsContainer.getComponents()) {
setPanelEnabled(c,val);
}
}
}
}
/**
* Find the closest boundary of a shape to a point.

View File

@ -667,6 +667,13 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
menuItem.addActionListener(new StorageOptions(getGuiFrame()));
startMenuEnabler.addMenuItem(menuItem);
fileMenu.add(menuItem);
if (isViewer) {
menuItem = new JMenuItem("Export Data ...");
menuItem.addActionListener(new ExportData(getGuiFrame()));
startMenuEnabler.addMenuItem(menuItem);
fileMenu.add(menuItem);
}
for (int i = 0; i < pamControllerInterface.getNumControlledUnits(); i++) {
@ -975,6 +982,19 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
}
}
class ExportData implements ActionListener {
private JFrame parentFrame;
public ExportData(JFrame parentFrame) {
super();
this.parentFrame = parentFrame;
}
public void actionPerformed(ActionEvent e) {
PamController.getInstance().exportData(parentFrame);
}
}
class MenuGeneralXMLExport implements ActionListener {
private JFrame parentFrame;
public MenuGeneralXMLExport(JFrame parentFrame) {
@ -1164,6 +1184,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
pamControllerInterface.orderModules(frame);
}
}
class menuArray implements ActionListener {
public void actionPerformed(ActionEvent ev){
ArrayManager.getArrayManager().showArrayDialog(getGuiFrame());

View File

@ -13,6 +13,8 @@ import javax.swing.JRadioButton;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import PamView.PamAWTUtils;
import PamView.PamView;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
@ -130,7 +132,11 @@ public class DataSelectorDialogPanel implements PamDialogPanel {
public void enableComponent() {
boolean enable = !disableButton.isSelected();
innerPanel.getDialogComponent().setEnabled(enable);
// System.out.println("Disable!!! " + enable);
PamAWTUtils.setPanelEnabled(innerPanel.getDialogComponent(), enable);
//disable in swing is not recursive
// innerPanel.getDialogComponent().setEnabled(enable);
}
@Override

View File

@ -79,7 +79,7 @@ public class CTMSettingsPanel extends TMSettingsPanel {
*/
private void setPanelEnabled(boolean enable) {
PamAWTUtils.setPanelEnabled(getFilterPanel(), enable);
PamAWTUtils.setPanelEnabled(getLocPanel(), enable);
PamAWTUtils.setPanelEnabled(getLocPanel(), enable);
}

View File

@ -1,5 +1,38 @@
package export.CSVExport;
public class CSVExportManager {
import java.io.File;
import java.util.List;
import PamguardMVC.PamDataUnit;
import export.PamDataUnitExporter;
public class CSVExportManager implements PamDataUnitExporter{
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean exportData(File fileName, List<PamDataUnit> dataUnits, boolean append) {
// TODO Auto-generated method stub
return false;
}
@Override
public String getFileExtension() {
return "csv";
}
@Override
public String getIconString() {
return "mdi2f-file-table-outline";
}
@Override
public String getName() {
return "CSV Export";
}
}

View File

@ -84,7 +84,7 @@ public abstract class MLDataUnitExport<T extends PamDataUnit<?, ?>> {
double datenumMT = PamCalendar.millistoDateNum(dataUnit.getTimeMilliseconds());
Matrix date = Mat5.newScalar(datenumMT);
mlStruct.set("date", date);
mlStruct.set("date", index, date);
//add detection specific data
mlStruct= addDetectionSpecificFields(mlStruct, index, dataUnit);

View File

@ -2,13 +2,20 @@ package export.MLExport;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.zip.Deflater;
import PamUtils.PamCalendar;
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.format.Mat5Writer;
import us.hebi.matlab.mat.types.Matrix;
import us.hebi.matlab.mat.types.Sink;
import us.hebi.matlab.mat.types.Sinks;
@ -24,12 +31,20 @@ import us.hebi.matlab.mat.util.Casts;
public class MLDetectionsManager implements PamDataUnitExporter {
public static final String extension = "mat";
// Creating date format
public static SimpleDateFormat dataFormat = new SimpleDateFormat(
"yyyyMMdd_HHmmss_SSS");
/**
*
* All the possible MLDataUnitExport export classes.
*/
ArrayList<MLDataUnitExport> mlDataUnitsExport = new ArrayList<MLDataUnitExport>();
ArrayList<MLDataUnitExport> mlDataUnitsExport = new ArrayList<MLDataUnitExport>();
private Sink sink;
private File currentFile;
public MLDetectionsManager(){
@ -55,12 +70,60 @@ public class MLDetectionsManager implements PamDataUnitExporter {
@Override
public boolean exportData(File fileName, List<PamDataUnit> dataUnits, boolean append) {
System.out.println("Export: " + dataUnits.size() + " data units " + append);
if (dataUnits==null || dataUnits.size()<1) {
//nothing to write but no error.
return true;
}
try {
Mat5File matFile = Mat5.newMatFile();
Sink sink = Sinks.newMappedFile(fileName, Casts.sint32(1000000));
Struct dataUnitsStruct = dataUnits2MAT(dataUnits);
// then
PamDataUnit minByTime = dataUnits
.stream()
.min(Comparator.comparing(PamDataUnit::getTimeMilliseconds))
.orElseThrow(NoSuchElementException::new);
//matlab struct must start with a letter.
Date date = new Date(minByTime.getTimeMilliseconds());
String entryName = "det_" + dataFormat.format( date);
//is there an existing sink? Is that sink writing to the correct file?
if (sink==null || !fileName.equals(currentFile)) {
System.out.println("Export: " + dataUnitsStruct.getNumDimensions() + entryName);
currentFile = fileName;
matFile.writeTo(sink);//Streams the data into a MAT file?
//create the sink for the next data so it can be appended to the file.
sink = Sinks.newStreamingFile(fileName);
//create the Mat File - gets all the headers right etc.
Mat5File matFile = Mat5.newMatFile();
matFile.addArray(entryName, dataUnitsStruct);
// matFile.addArray("two", Mat5.newScalar(2));
matFile.writeTo(sink);
matFile.close();
}
else {
//write to the mat file without loading all contents into memory.
Mat5Writer writer = Mat5.newWriter(sink);
writer
.writeArray(entryName, dataUnitsStruct)
.setDeflateLevel(Deflater.NO_COMPRESSION);
// .writeArray("three", Mat5.newScalar(2));
writer.flush();
}
return true;
} catch (IOException e) {
// TODO Auto-generated catch block
@ -68,7 +131,6 @@ public class MLDetectionsManager implements PamDataUnitExporter {
return false;
}
return false;
}
/**

View File

@ -1,11 +1,14 @@
package export;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import PamUtils.PamCalendar;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import export.CSVExport.CSVExportManager;
import export.MLExport.MLDetectionsManager;
import export.RExport.RExportManager;
import export.layoutFX.ExportParams;
@ -18,9 +21,9 @@ import export.wavExport.WavFileExportManager;
public class PamExporterManager {
/**
* The number of data units to save before saving.
* The number of data units to save before saving. This prevents too much being stored in memory
*/
private static int BUFFER_SIZE = 1000;
private static int BUFFER_SIZE = 10000;
/**
* Keep the file size to around 1GB per file
@ -47,6 +50,10 @@ public class PamExporterManager {
* Reference to the current export paramters.
*/
private ExportParams exportParams = new ExportParams();
// Creating date format
public static SimpleDateFormat dataFormat = new SimpleDateFormat(
"yyyy_MM_dd_HHmmss");
public PamExporterManager() {
pamExporters = new ArrayList<PamDataUnitExporter>();
@ -55,19 +62,35 @@ public class PamExporterManager {
pamExporters.add(new MLDetectionsManager());
pamExporters.add(new RExportManager());
pamExporters.add(new WavFileExportManager());
pamExporters.add(new CSVExportManager());
}
/**
* Add a data unit to the export list.
* @param force - true to force saving of data e.g. at the end of processing.
*/
public boolean exportDataUnit(PamDataUnit<?, ?> dataUnit) {
public boolean exportDataUnit(PamDataUnit<?, ?> dataUnit, boolean force) {
boolean exportOK = true;
if (dataUnit==null) {
if (force) {
System.out.println("Write data 1!!" + dataUnitBuffer.size());
exportOK = pamExporters.get(exportParams.exportChoice).exportData(currentFile, dataUnitBuffer, true);
dataUnitBuffer.clear();
}
return true;
}
//if the data unit is null then save everything to the buffer.
if (currentFile == null || isFileSizeMax(currentFile)) {
Date date = new Date(dataUnit.getTimeMilliseconds());
String newFileName = "PAM_" + dataFormat.format(date);
//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)
String fileName = (exportParams.folder + File.separator + newFileName
+ "." + pamExporters.get(exportParams.exportChoice).getFileExtension());
currentFile = new File(fileName);
@ -75,7 +98,11 @@ public class PamExporterManager {
dataUnitBuffer.add(dataUnit);
if (BUFFER_SIZE>=BUFFER_SIZE) {
// System.out.println("Write data unit " + dataUnitBuffer.size() + " to: "+ currentFile);
if (dataUnitBuffer.size()>=BUFFER_SIZE || force) {
System.out.println("Write data 2!!" + dataUnitBuffer.size());
exportOK = pamExporters.get(exportParams.exportChoice).exportData(currentFile, dataUnitBuffer, true);
dataUnitBuffer.clear();
}
@ -101,6 +128,8 @@ public class PamExporterManager {
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;
@ -127,5 +156,19 @@ public class PamExporterManager {
}
public void setCurrentFile(File file) {
this.currentFile=file;
}
public ExportParams getExportParams() {
return exportParams;
}
public void setExportParams(ExportParams currentParams) {
exportParams=currentParams;
}
}

View File

@ -1,14 +1,20 @@
package export.RExport;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import org.renjin.eval.Context;
import org.renjin.primitives.io.serialization.RDataWriter;
import org.renjin.sexp.ListVector;
import org.renjin.sexp.PairList;
import PamguardMVC.PamDataUnit;
import export.PamDataUnitExporter;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
/**
* Handles exporting pam data units into an rdata.
@ -22,7 +28,17 @@ public class RExportManager implements PamDataUnitExporter {
*
* All the possible RDataUnit export classes.
*/
ArrayList<RDataUnitExport> mlDataUnitsExport = new ArrayList<RDataUnitExport>();
ArrayList<RDataUnitExport> mlDataUnitsExport = new ArrayList<RDataUnitExport>();
private FileOutputStream fos;
private GZIPOutputStream zos;
private File currentFileName ;
private RDataWriter writer;
private Context context;
public RExportManager(){
@ -32,6 +48,56 @@ public class RExportManager implements PamDataUnitExporter {
mlDataUnitsExport.add(new RRawExport()); //should be last in case raw data holders have specific exporters
}
@Override
public boolean exportData(File fileName, List<PamDataUnit> dataUnits, boolean append) {
//convert the data units to
RData dataUnitsR = dataUnits2R(dataUnits);
// System.out.println("Export R file!!" + dataUnits.size());
//now write the file
try {
//is there an existing writer? Is that writer writing to the correct file?
if (zos==null || fileName.equals(currentFileName)) {
if (zos!=null) {
zos.close();
writer.close();
}
currentFileName = fileName;
// System.out.println("MLDATA size: "+ mlData.size());
// System.out.println("---MLArray----");
// for (int i=0; i<mlData.size(); i++) {
// System.out.println(mlData.get(i));
// System.out.println("-------");
// }
// System.out.println("--------------");
context = Context.newTopLevelContext();
fos = new FileOutputStream(fileName);
zos = new GZIPOutputStream(fos);
return true;
}
writer = new RDataWriter(context, zos);
writer.save(dataUnitsR.rData.build());
return true;
}
catch (IOException e1) {
e1.printStackTrace();
return false;
}
}
/**
* Check whether there are compatible data units to be exported.
* @param dataUnits - the data unit list
@ -44,7 +110,7 @@ public class RExportManager implements PamDataUnitExporter {
}
return false;
}
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
for (int i=0; i<mlDataUnitsExport.size(); i++){
@ -58,23 +124,23 @@ public class RExportManager implements PamDataUnitExporter {
}
return false;
}
/**
* Sort a list of data units into lists of the same type of units. Convert to a list of structures.
* @param dataUnits - a list of data units to convert to matlab structures.
* @return list of list of R strucutures ready for saving to .RData file.
*/
public RData dataUnits2R(ArrayList<PamDataUnit> dataUnits){
public RData dataUnits2R(List<PamDataUnit> dataUnits){
//if there's a mixed bunch of data units then we want separate arrays of structures. So a structure of arrays of structures.
//so, need to sort compatible data units.
PairList.Builder allData = new PairList.Builder();
ArrayList<String> dataUnitTypes = new ArrayList<String>();
//iterate through possible export functions.
for (int i=0; i<mlDataUnitsExport.size(); i++){
//first need to figure out how many data units there are.
int n=0;
for (int j=0; j<dataUnits.size(); j++){
@ -83,12 +149,12 @@ public class RExportManager implements PamDataUnitExporter {
n++;
}
}
if (n==0) continue; //no need to do anything else. There are no data units of this type.
ListVector.NamedBuilder dataListArray = new ListVector.NamedBuilder();
ListVector.NamedBuilder dataList;
n=0;
//allocate the class now.
@ -100,14 +166,14 @@ public class RExportManager implements PamDataUnitExporter {
n++;
}
}
if (n>1) {
allData.add(mlDataUnitsExport.get(i).getName(), dataListArray.build());
dataUnitTypes.add(mlDataUnitsExport.get(i).getName());
}
}
RData rData = new RData();
rData.rData=allData;
rData.dataUnitTypes=dataUnitTypes;
@ -115,19 +181,19 @@ public class RExportManager implements PamDataUnitExporter {
//now ready to save.
return rData;
}
/**
* Simple class to hold RData and list of the data unit names whihc were saved.
* @author jamie
*
*/
public class RData {
/**
* The RData raedy to save
*/
public PairList.Builder rData;
/**
* List of the names of the types of data units whihc were saved.
*/
@ -136,12 +202,6 @@ public class RExportManager implements PamDataUnitExporter {
@Override
public boolean exportData(File fileName, List<PamDataUnit> dataUnits, boolean append) {
// TODO Auto-generated method stub
return false;
}
@Override
public String getFileExtension() {
return "RData";
@ -157,6 +217,6 @@ public class RExportManager implements PamDataUnitExporter {
return "R data";
}
}

View File

@ -13,7 +13,7 @@ public class ExportParams implements Serializable, Cloneable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 2L;
/**
* The index of the export choice.
@ -25,6 +25,11 @@ public class ExportParams implements Serializable, Cloneable {
*/
public String folder = System.getProperty("user.home");
/**
* The maximum file size in Megabytes
*/
public Double maximumFileSize = 1000.0;
@Override
public ExportParams clone() {
try {

View File

@ -1,6 +1,5 @@
package export.swing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
@ -11,14 +10,10 @@ import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.JTextField;
@ -29,13 +24,13 @@ import javax.swing.border.TitledBorder;
import org.kordamp.ikonli.Ikon;
import org.kordamp.ikonli.fileicons.FileIcons;
import org.kordamp.ikonli.materialdesign2.MaterialDesignA;
import org.kordamp.ikonli.materialdesign2.MaterialDesignF;
import org.kordamp.ikonli.swing.FontIcon;
import PamController.PamController;
import PamUtils.PamFileChooser;
import PamView.dialog.PamButton;
import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamPanel;
import PamguardMVC.PamDataBlock;
@ -43,6 +38,7 @@ import export.PamExporterManager;
import export.layoutFX.ExportParams;
import offlineProcessing.OLProcessDialog;
import offlineProcessing.OfflineTaskGroup;
import offlineProcessing.TaskStatus;
/**
* Handles an offline dialog for processing offline data and exporting to bespoke file types.
@ -150,20 +146,26 @@ public class ExportProcessDialog {
public ExportOLDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) {
super(parentFrame, taskGroup, title);
// TODO Auto-generated constructor stub
//remove the notes panel - don't need this for export.
super.removeNotePanel();
//remove delete database entried - not used.
super.getDeleteOldDataBox().setVisible(false);
//construc tthe panel.
PamPanel mainPanel = new PamPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.setBorder(new TitledBorder("Export Settings"));
buttonGroup = new ButtonGroup();
PamPanel buttonPanel = new PamPanel();
ActionListener listener = actionEvent -> {
System.out.println(actionEvent.getActionCommand() + " Selected");
// System.out.println(actionEvent.getActionCommand() + " Selected");
//TODO set the buttons to be disabled or enabled.
enableTasks(getExportSelection());
};
exportButtons = new JToggleButton[exportManager.getNumExporters()];
@ -178,7 +180,7 @@ public class ExportProcessDialog {
b.setIcon(icon);
b.addActionListener(listener);
exportButtons[i]=b;
buttonGroup.add(b);
buttonPanel.add(b);
@ -192,8 +194,8 @@ public class ExportProcessDialog {
c.gridy = 0;
addComponent(p, exportTo = new JTextField(), c);
exportTo.setMinimumSize(new Dimension(170, 25));
exportTo.setPreferredSize(new Dimension(170, 25));
exportTo.setMinimumSize(new Dimension(180, 25));
exportTo.setPreferredSize(new Dimension(180, 25));
c.gridx +=3;
c.gridwidth = 1;
@ -216,34 +218,51 @@ public class ExportProcessDialog {
c.gridx = 1;
c.gridy++;
c.gridwidth = 2;
JLabel label = new JLabel("Maximum file size", SwingConstants.RIGHT);
addComponent(p, label, c);
c.gridwidth = 1;
c.gridx +=2;
SpinnerListModel list = new SpinnerListModel(new Double[] {10.,30., 60., 100., 200., 300., 600., 1000.});
spinner = new JSpinner(list);
//don't want the user to to able to set values
((DefaultEditor) spinner.getEditor()).getTextField().setEditable(false);
spinner.setBounds(50, 80, 70, 100);
addComponent(p, spinner, c);
c.gridx ++;
addComponent(p, new JLabel("MB"), c);
mainPanel.add(p);
mainPanel.add(buttonPanel);
//add the main panel at a different index.
getMainPanel().add(mainPanel, 1);
pack();
}
/**
* Enable which task are disables and enabled.
* @param exportSelection
*/
private void enableTasks(int exportSelection) {
this.currentParams = getExportParams();
exportManager.setExportParams(currentParams);
// ExportTask task;
// for (int i=0; i<this.getTaskGroup().getNTasks(); i++) {
// task = (ExportTask) this.getTaskGroup().getTask(i);
// }
enableControls();
}
private Ikon getIconFromString(String iconString) {
@ -262,20 +281,57 @@ public class ExportProcessDialog {
case "mdi2f-file-music":
icon=MaterialDesignF.FILE_MUSIC;
break;
case "mdi2f-file-table-outline":
icon=MaterialDesignF.FILE_TABLE_OUTLINE;
break;
}
return icon;
}
private int getExportSelection() {
int sel=-1;
for (int i=0; i<exportButtons.length; i++) {
if (this.exportButtons[i].isSelected()) {
sel=i;
break;
}
}
return sel;
}
public ExportParams getExportParams() {
currentParams.folder = null;
if (exportTo.getText().length()>0) {
File file = new File(exportTo.getText());
if (!(file.exists() && file.isDirectory())) {
currentParams.folder = null;
}
else {
currentParams.folder = file.getAbsolutePath();
}
}
currentParams.exportChoice = getExportSelection();
currentParams.maximumFileSize = (Double) spinner.getValue();
return currentParams;
}
@Override
public boolean getParams() {
//make sure we update the current paramters before processing starts.
this.currentParams = getExportParams();
exportManager.setExportParams(currentParams);
if (this.currentParams.folder==null) {
return PamDialog.showWarning(super.getOwner(), "No folder or file selected", "You must select an output folder");
}
return super.getParams();
}
@ -286,8 +342,14 @@ public class ExportProcessDialog {
buttonGroup.clearSelection();
exportButtons[params.exportChoice].setSelected(true);
exportTo.setText(currentParams.folder);
spinner.setValue(currentParams.maximumFileSize);
}
}
@ -304,6 +366,7 @@ public class ExportProcessDialog {
return "Export Data";
}
}

View File

@ -25,12 +25,15 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
/**
* The data selector for the data block
*/
private DataSelector dataSelector;
private DataSelector dataSelector;
private boolean canExport;
public ExportTask(PamDataBlock<PamDataUnit<?, ?>> parentDataBlock, PamExporterManager exporter) {
super(parentDataBlock);
this.exporter = exporter;
dataSelector=parentDataBlock.getDataSelectCreator().getDataSelector(this.getUnitName() +"_clicks", false, null);
}
@ -41,20 +44,25 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
@Override
public boolean processDataUnit(PamDataUnit<?, ?> dataUnit) {
exporter.exportDataUnit(dataUnit);
return true;
if (dataSelector==null) exporter.exportDataUnit(dataUnit, false);
else if (dataSelector.scoreData(dataUnit)>0) {
exporter.exportDataUnit(dataUnit, false);
}
return false; //we don't need to indicate that anything has changed - we are just exporting.
}
@Override
public void newDataLoad(long startTime, long endTime, OfflineDataMapPoint mapPoint) {
// TODO Auto-generated method stub
// System.out.println("EXPORTER: new data load");
}
@Override
public void loadedDataComplete() {
//force the exporter so save any remaning data units in the buffer
exporter.exportDataUnit(null);
System.out.println("EXPORTER: loaded data complete");
//force the exporter so save any renaming data units in the buffer
exporter.exportDataUnit(null, true);
exporter.setCurrentFile(null);
}
/**
@ -79,4 +87,25 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
}
/**
* Set whether the task can export based on the current selection
* @param exportSelection - the index of the selected exporter
*/
public boolean canExport(int exportSelection) {
return exporter.getExporter(exportSelection).hasCompatibleUnits(getDataBlock().getUnitClass());
}
@Override
public boolean canRun() {
boolean can = getDataBlock() != null;
if (can) {
//check whether we can export based on the export selection
can = canExport(exporter.getExportParams().exportChoice);
}
return can;
}
}

View File

@ -47,20 +47,20 @@ public class FormsTabPanel implements PamTabPanel {
// keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();
// keyManager.addKeyEventDispatcher(new LoggerKeyEventDispatcher());
/** Global (OS-level) hotkey manager:
* jnativehook supported systems: Windows, X11, MacOS
*
*/
try {
LogManager.getLogManager().reset();
GlobalScreen.setEventDispatcher(new SwingDispatchService());
GlobalScreen.registerNativeHook();
GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
}
// /** Global (OS-level) hotkey manager:
// * jnativehook supported systems: Windows, X11, MacOS
// *
// */
// try {
// LogManager.getLogManager().reset();
// GlobalScreen.setEventDispatcher(new SwingDispatchService());
// GlobalScreen.registerNativeHook();
// GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
// }
// catch (NativeHookException ex) {
// System.err.println("There was a problem registering the native hook.");
// System.err.println(ex.getMessage());
// }
}
@Override

View File

@ -13,7 +13,6 @@ import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
@ -39,7 +38,6 @@ import PamView.panel.PamAlignmentPanel;
import PamView.panel.PamPanel;
import PamView.panel.PamProgressBar;
import PamguardMVC.PamDataBlock;
import export.layoutFX.ExportParams;
import offlineProcessing.logging.OldTaskData;
import offlineProcessing.logging.TaskLogging;
import offlineProcessing.superdet.OfflineSuperDetFilter;
@ -95,7 +93,7 @@ public class OLProcessDialog extends PamDialog {
// public static ImageIcon settings = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png"));
public static FontIcon settings = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY);
public static FontIcon settings = FontIcon.of(MaterialDesignC.COG, 20, Color.DARK_GRAY);
TaskStatus currentStatus = TaskStatus.IDLE;
@ -105,6 +103,13 @@ public class OLProcessDialog extends PamDialog {
*/
private JPanel mainPanel;
private JPanel notePanel;
/**
* True if a note is required for the
*/
private boolean isNeedaNote = true;
public OLProcessDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) {
super(parentFrame, title, false);
@ -165,7 +170,7 @@ public class OLProcessDialog extends PamDialog {
c.gridy++;
}
JPanel notePanel = new JPanel(new BorderLayout());
notePanel = new JPanel(new BorderLayout());
notePanel.setBorder(new TitledBorder("Notes"));
noteText = new DBTextArea(2, 40, TaskLogging.TASK_NOTE_LENGTH);
noteText.getComponent().setToolTipText("Notes to add to database record of complete tasks");
@ -185,11 +190,14 @@ public class OLProcessDialog extends PamDialog {
c.gridwidth = 1;
addComponent(progressPanel, new JLabel("File ", SwingConstants.RIGHT), c);
c.gridx++;
c.gridwidth = 2;
addComponent(progressPanel, loadedProgress = new PamProgressBar(0, 100), c);
c.gridx = 0;
c.gridy++;
c.gridwidth = 1;
addComponent(progressPanel, new JLabel("All Data ", SwingConstants.RIGHT), c);
c.gridx++;
c.gridwidth = 2;
addComponent(progressPanel, globalProgress = new PamProgressBar(00, 100), c);
mainPanel.add(dataSelectPanel);
@ -220,6 +228,15 @@ public class OLProcessDialog extends PamDialog {
}
/**
* Remove the notes panel.
*/
public void removeNotePanel() {
isNeedaNote = false;
mainPanel.remove(notePanel);
pack();
}
/**
* Get the main panel. This can be used to add additional controls if needed.
* @return the main panel.
@ -310,7 +327,7 @@ public class OLProcessDialog extends PamDialog {
taskCheckBox[i].setSelected(false);
}
if (settingsButton[i] != null) {
settingsButton[i].setEnabled(nr);
settingsButton[i].setEnabled(aTask.canRun() && nr);
}
if (taskCheckBox[i].isSelected()) {
selectedTasks++;
@ -368,7 +385,7 @@ public class OLProcessDialog extends PamDialog {
}
String note = noteText.getText();
if (note == null || note.length() == 0) {
if ((note == null || note.length() == 0) && isNeedaNote) {
return PamDialog.showWarning(super.getOwner(), "Task note", "you must enter a note about what you are doing");
}
taskGroupParams.taskNote = note;
@ -376,6 +393,7 @@ public class OLProcessDialog extends PamDialog {
return true;
}
public void setTaskToolTips() {
int nTasks = taskGroup.getNTasks();
@ -842,6 +860,24 @@ public class OLProcessDialog extends PamDialog {
public OfflineTaskGroup getTaskGroup() {
return this.taskGroup;
}
/**
* Check whether a note is required.
* @return true if a note is required.
*/
public boolean isNeedaNote() {
return isNeedaNote;
}
/**
* Set whether a note is required before processing
* @param isNeedaNote - true to require user to input a note.
*/
public void setNeedaNote(boolean isNeedaNote) {
this.isNeedaNote = isNeedaNote;
}
}

View File

@ -0,0 +1,39 @@
package pamguard;
import java.sql.Connection;
import java.sql.SQLException;
import org.sqlite.SQLiteConfig;
import generalDatabase.sqlite.SqliteSQLTypes;
public class PAMGuard_sqlite {
public static void main(String[] args) {
String dbName = "/Users/jdjm/Desktop/section2_cpod/hyskeir_pamguard.sqlite3";
/*
* Don't use the driver manager, but open from the built in command in
* SQLiteConfig. This will then correctly set the dateformat of the database.
*/
SQLiteConfig config = new SQLiteConfig();
config.setSharedCache(true);
config.enableRecursiveTriggers(true);
config.enableLoadExtension(true);
config.setDateClass(SqliteSQLTypes.dateClass.getValue());
config.setDateStringFormat(SQLiteConfig.DEFAULT_DATE_STRING_FORMAT);
Connection con = null;
try {
con = config.createConnection("jdbc:sqlite:" + dbName);
con.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Connection: " + con);
}
}