mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
Updates to exporter and data map in FX GUI
This commit is contained in:
parent
791dad9439
commit
2c11ff435b
@ -6,7 +6,7 @@
|
||||
<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/Amazon Coretto 21">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
|
@ -65,7 +65,7 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
|
||||
/**
|
||||
* Pane which allows users to change scale on datamap.
|
||||
*/
|
||||
private ScalePaneFX scalePane;
|
||||
private DataMapSettingsPane dataMapSettingsPane;
|
||||
|
||||
private PamVBox settingsPane;
|
||||
|
||||
@ -87,14 +87,14 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
|
||||
//create all the different panes,
|
||||
summaryPane = new SummaryPaneFX(dataMapControl, this);
|
||||
|
||||
scalePane=new ScalePaneFX(dataMapControl,this);
|
||||
|
||||
scrollingDataPanel= new ScrollingDataPaneFX(dataMapControl, this);
|
||||
|
||||
dataMapSettingsPane=new DataMapSettingsPane(dataMapControl,this);
|
||||
|
||||
//create the setting spane
|
||||
settingsPane=new PamVBox();
|
||||
// settingsPane.getChildren().add(summaryPane);
|
||||
settingsPane.getChildren().add(scalePane);
|
||||
settingsPane.getChildren().add(dataMapSettingsPane.getContentNode());
|
||||
settingsPane.setPadding(new Insets(40,10,10,10));
|
||||
settingsPane.setPrefWidth(HIDE_PANE_WIDTH);
|
||||
|
||||
@ -178,12 +178,11 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
|
||||
* Called from ScalePanel when anything
|
||||
* to do with scaling changes.
|
||||
*/
|
||||
@Deprecated
|
||||
public void scaleChanged() {
|
||||
if (scalePane == null || scrollingDataPanel == null) {
|
||||
if (dataMapSettingsPane == null || scrollingDataPanel == null) {
|
||||
return;
|
||||
}
|
||||
scalePane.getParams(dataMapControl.dataMapParameters);
|
||||
dataMapSettingsPane.getParams(dataMapControl.dataMapParameters);
|
||||
//scrollingDataPanel.scaleChange();
|
||||
}
|
||||
|
||||
@ -228,24 +227,30 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
|
||||
switch (changeType) {
|
||||
case PamControllerInterface.INITIALIZATION_COMPLETE:
|
||||
scrollingDataPanel.updateScrollBar();
|
||||
scalePane.checkDataGramPane();
|
||||
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
|
||||
this.repaintAll();
|
||||
break;
|
||||
case PamControllerInterface.CHANGED_OFFLINE_DATASTORE:
|
||||
scrollingDataPanel.updateScrollBar();
|
||||
scalePane.checkDataGramPane();
|
||||
dataMapSettingsPane.checkDataGramPane();
|
||||
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
|
||||
break;
|
||||
case PamControllerInterface.ADD_CONTROLLEDUNIT:
|
||||
scalePane.checkDataGramPane();
|
||||
case PamControllerInterface.REMOVE_CONTROLLEDUNIT:
|
||||
scalePane.checkDataGramPane();
|
||||
dataMapSettingsPane.checkDataGramPane();
|
||||
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
|
||||
break;
|
||||
case PamControllerInterface.INITIALIZE_LOADDATA:
|
||||
case PamControllerInterface.EXTERNAL_DATA_IMPORTED:
|
||||
scrollingDataPanel.updateScrollBar();
|
||||
scalePane.checkDataGramPane();
|
||||
dataMapSettingsPane.checkDataGramPane();
|
||||
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
|
||||
this.repaintAll();
|
||||
break;
|
||||
case PamControllerInterface.OFFLINE_DATA_LOADED:
|
||||
scrollingDataPanel.updateScrollBar();
|
||||
scalePane.checkDataGramPane();
|
||||
dataMapSettingsPane.checkDataGramPane();
|
||||
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
|
||||
this.repaintAll();
|
||||
break;
|
||||
case PamControllerInterface.DATA_LOAD_COMPLETE:
|
||||
@ -304,4 +309,22 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current number of data stream panes
|
||||
* @return the number of data stream panes
|
||||
*/
|
||||
public int getNumDataStreamPanes() {
|
||||
return this.scrollingDataPanel.getNumDataStreamPanes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a data stream pane.
|
||||
* @param n - the index of the data stream pane
|
||||
* @return the data stream pane or null if the index is out of bounds.
|
||||
*/
|
||||
public DataStreamPaneFX getDataStreamPane(int n) {
|
||||
return this.scrollingDataPanel.getDataSyreamPane( n);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
489
src/dataMap/layoutFX/DataMapSettingsPane.java
Normal file
489
src/dataMap/layoutFX/DataMapSettingsPane.java
Normal file
@ -0,0 +1,489 @@
|
||||
package dataMap.layoutFX;
|
||||
|
||||
import dataGram.DatagramManager;
|
||||
import dataGram.DatagramScaleInformation;
|
||||
import dataGram.DatagramSettings;
|
||||
import dataMap.DataMapControl;
|
||||
import dataMap.DataMapParameters;
|
||||
import PamController.PamController;
|
||||
import PamUtils.PamCalendar;
|
||||
import binaryFileStorage.BinaryStore;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.comboBox.ColorComboBox;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxNodes.sliders.ColourRangeSlider;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
import pamViewFX.fxNodes.utilsFX.ColourArray;
|
||||
import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType;
|
||||
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
|
||||
|
||||
/**
|
||||
* Settings pane which allows users to change settings for data maps.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class DataMapSettingsPane extends DynamicSettingsPane<DataMapParameters> {
|
||||
|
||||
/*
|
||||
* Reference to the data map control.
|
||||
*/
|
||||
private DataMapControl dataMapControl;
|
||||
|
||||
/**
|
||||
* Reference to the dataMapPane.
|
||||
*/
|
||||
private DataMapPaneFX dataMapPane;
|
||||
|
||||
// /**
|
||||
// * The slider which determines time scale.
|
||||
// */
|
||||
// private Slider timeSlider;
|
||||
|
||||
/**
|
||||
* Shows the time scale in pix/hour
|
||||
*/
|
||||
private Label timeScaleLabel;
|
||||
|
||||
/**
|
||||
* Selects unit count on vertical scale
|
||||
*/
|
||||
private ComboBox<String> scaleBox;
|
||||
|
||||
/**
|
||||
* Check box for log vertical scale.
|
||||
*/
|
||||
private PamToggleSwitch logScaleToggle;
|
||||
|
||||
// /**
|
||||
// * The chosen time values.
|
||||
// */
|
||||
// private double[] timeScaleChoices = DataMapParameters.hScaleChoices;
|
||||
|
||||
/**
|
||||
* Combo box holding options to channge the datargam bin size
|
||||
*/
|
||||
private ComboBox<String> datagramBox;
|
||||
|
||||
/**
|
||||
* Holds a list of times for the datagram bin size.
|
||||
*/
|
||||
private ComboBox<String> dataGramComboBox;
|
||||
|
||||
/**
|
||||
* Holds everything.
|
||||
*/
|
||||
private PamVBox holder;
|
||||
|
||||
/**
|
||||
* Grid pane with settings for the data scales
|
||||
*/
|
||||
private PamGridPane scaleSettingsPane;
|
||||
|
||||
private Label dataGramLabel;
|
||||
|
||||
private ComboBox<String> dataGramBox;
|
||||
|
||||
/**
|
||||
* Holdes datagram settings.
|
||||
*/
|
||||
private PamVBox dataGramSettingsPane;
|
||||
|
||||
private DataGramColPane dataGramColPane;
|
||||
|
||||
private PamBorderPane mainPain;
|
||||
|
||||
|
||||
|
||||
public DataMapSettingsPane(DataMapControl dataMapControl, DataMapPaneFX dataMapPane) {
|
||||
super(null);
|
||||
this.dataMapControl = dataMapControl;
|
||||
this.dataMapPane = dataMapPane;
|
||||
|
||||
// //create the holder pane.
|
||||
// PamVBox vBoxHolder=new PamVBox();
|
||||
// vBoxHolder.setSpacing(5);
|
||||
// Label title=new Label("Scales");
|
||||
// PamGuiManagerFX.titleFont2style(title);
|
||||
// vBoxHolder.getChildren().addAll(title, controlPane);
|
||||
|
||||
//add the scale
|
||||
holder=new PamVBox();
|
||||
holder.setSpacing(5);
|
||||
|
||||
Label scaleLabel = new Label("Data Scale");
|
||||
PamGuiManagerFX.titleFont2style(scaleLabel);
|
||||
holder.getChildren().add(scaleLabel);
|
||||
holder.getChildren().add(scaleSettingsPane = createScalePane());
|
||||
|
||||
//adds the datagram settings pane which is dependent on binary storage.
|
||||
checkDataGramPane();
|
||||
|
||||
mainPain = new PamBorderPane();
|
||||
mainPain.setCenter(holder);
|
||||
|
||||
//set params for the pane
|
||||
setParams(dataMapControl.dataMapParameters);
|
||||
checkDataGramPane(); // create datagram pane if a binary store already added.
|
||||
sayHScale();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a settings pane for the data gram if a binary store is present.
|
||||
*/
|
||||
public void checkDataGramPane(){
|
||||
if (BinaryStore.findBinaryStoreControl()!=null){
|
||||
DatagramManager dataGramManager=BinaryStore.findBinaryStoreControl().getDatagramManager();
|
||||
if (dataGramManager!=null && dataGramSettingsPane==null) {
|
||||
PamVBox datagramholder = new PamVBox();
|
||||
datagramholder.setSpacing(5);
|
||||
Label datagramLabel = new Label("Datagrams");
|
||||
PamGuiManagerFX.titleFont2style(datagramLabel);
|
||||
datagramholder.getChildren().add(datagramLabel);
|
||||
datagramholder.getChildren().add(createDatagramPane(dataGramManager));
|
||||
|
||||
holder.getChildren().add(this.dataGramSettingsPane = datagramholder);
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.getChildren().remove(this.dataGramSettingsPane);
|
||||
datagramBox=null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the a datagram combo box to change the size of the datagram
|
||||
* @param dataGramManager - the datagram manager for the current biinary store.
|
||||
* @return a combo box with datagram bin sizes.
|
||||
*/
|
||||
private ComboBox<String> createDataGramBinPane(DatagramManager dataGramManager){
|
||||
|
||||
dataGramComboBox=new ComboBox<String>(createDurationList(dataGramManager));
|
||||
|
||||
dataGramComboBox.getSelectionModel().select(durationToString(dataGramManager.getDatagramSettings().datagramSeconds*1000L));
|
||||
dataGramComboBox.valueProperty().addListener(( ov, t, t1) -> {
|
||||
if (t==t1) return;
|
||||
else {
|
||||
PamController.getInstance();
|
||||
boolean ans=PamDialogFX.showWarning(PamController.getMainStage(), "Warning", "Recalculating the datagram for a large dataset may take a long time" +
|
||||
"Are you sure you want to continue");
|
||||
if (ans){
|
||||
int index=dataGramComboBox.getSelectionModel().getSelectedIndex();
|
||||
//messy- datagramSeconfds should be in millis but left for backwards compatibility.
|
||||
dataGramManager.getDatagramSettings().datagramSeconds=(int) (DatagramSettings.defaultDatagramSeconds[index]/1000);
|
||||
dataGramManager.updateDatagrams();
|
||||
dataMapPane.repaintAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return dataGramComboBox;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert duration to string.
|
||||
* @param duration in millis.
|
||||
*/
|
||||
private String durationToString(long duration){
|
||||
return (" " + PamCalendar.formatDuration(duration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create list of load times.
|
||||
* @return list of load times duration.
|
||||
*/
|
||||
private ObservableList<String> createDurationList(DatagramManager dataGramManager){
|
||||
ObservableList<String> loadTimeList=FXCollections.observableArrayList();
|
||||
for (int i=0; i<DatagramSettings.defaultDatagramSeconds.length; i++){
|
||||
loadTimeList.add(durationToString(DatagramSettings.defaultDatagramSeconds[i]));
|
||||
}
|
||||
return loadTimeList;
|
||||
}
|
||||
|
||||
|
||||
private Pane createDatagramPane(DatagramManager dataGramManager) {
|
||||
|
||||
dataGramLabel= new Label("Datagram bin size");
|
||||
ComboBox<String> datagramBinsBox = createDataGramBinPane(dataGramManager);
|
||||
|
||||
//Pane for colouring datagrams.
|
||||
dataGramBox=new ComboBox<String> ();
|
||||
|
||||
//find all datagrams.
|
||||
updateDataStreamBox();
|
||||
|
||||
dataGramBox.setOnAction((action)->{
|
||||
dataGramColPane.setDataStreamPanel(dataMapPane.getDataStreamPane(dataGramBox.getSelectionModel().getSelectedIndex()));
|
||||
});
|
||||
|
||||
//holds settings for the datagram
|
||||
dataGramColPane = new DataGramColPane();
|
||||
|
||||
PamGridPane holder = new PamGridPane();
|
||||
holder.setHgap(5);
|
||||
holder.setVgap(5);
|
||||
//holder.setGridLinesVisible(true);
|
||||
|
||||
int row = 0;
|
||||
|
||||
holder.add(dataGramLabel, 0,row);
|
||||
holder.add(datagramBinsBox, 1, row);
|
||||
|
||||
row++;
|
||||
|
||||
holder.add(new Label("Select datagram"), 0, row);
|
||||
holder.add(dataGramBox, 1, row);
|
||||
|
||||
row++;
|
||||
|
||||
GridPane.setHgrow(dataGramColPane, Priority.ALWAYS);
|
||||
holder.add(dataGramColPane, 0, row);
|
||||
|
||||
//dunno why this always had to be set after the child has been added to work.
|
||||
GridPane.setColumnSpan(dataGramColPane, 3);
|
||||
|
||||
//hack to make sure the third column of the gris expands to fit the pane
|
||||
ColumnConstraints rightCol = new ColumnConstraints();
|
||||
rightCol.setHgrow(Priority.ALWAYS);
|
||||
holder.getColumnConstraints().addAll(new ColumnConstraints(), new ColumnConstraints(), rightCol);
|
||||
|
||||
return holder;
|
||||
|
||||
}
|
||||
|
||||
private void updateDataStreamBox() {
|
||||
System.out.println("UPDATE DATA STREAM BOX: " + this.dataMapPane.getNumDataStreamPanes());
|
||||
for (int i=0; i<this.dataMapPane.getNumDataStreamPanes(); i++) {
|
||||
if (dataMapPane.getDataStreamPane(i).getScaleType() == DatagramScaleInformation.PLOT_3D) {
|
||||
dataGramBox.getItems().add(dataMapPane.getDataStreamPane(i).getDataName().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allows the user to change datagram colours.
|
||||
*
|
||||
*/
|
||||
public class DataGramColPane extends PamBorderPane {
|
||||
|
||||
|
||||
private ColourRangeSlider colourSlider;
|
||||
|
||||
private Label ampLabel;
|
||||
|
||||
private ColorComboBox colorBox;
|
||||
|
||||
private ColourArrayType colorArray = ColourArrayType.HSV;
|
||||
|
||||
private DataStreamPaneFX dataStreamPane;
|
||||
|
||||
public DataGramColPane() {
|
||||
|
||||
//create colour slider
|
||||
//colour slider
|
||||
colourSlider=new ColourRangeSlider();
|
||||
colourSlider.setShowTickMarks(false);
|
||||
colourSlider.setShowTickLabels(false);
|
||||
colourSlider.setOrientation(Orientation.HORIZONTAL);
|
||||
//amplifier label
|
||||
// String dBRef = GlobalMedium.getdBRefString(PamController.getInstance().getGlobalMediumManager().getCurrentMedium());
|
||||
Label ampLabel = new Label("Colour scale");
|
||||
|
||||
colorBox=new ColorComboBox(ColorComboBox.COLOUR_ARRAY_BOX);
|
||||
colorBox.setPrefWidth(80);
|
||||
|
||||
colourSlider.highValueProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
|
||||
});
|
||||
|
||||
//Change the colour of the colour slider when combo box is changed.
|
||||
colorBox.valueProperty().addListener(new ChangeListener<String>() {
|
||||
@Override public void changed(ObservableValue<? extends String> ov, String t, String t1) {
|
||||
//change the colour of the colour range slider.
|
||||
setColours();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
colorBox.setValue(ColourArray.getName(getColourArrayType()));
|
||||
|
||||
//need to set up alignment properly. //FIXME- a bit messy
|
||||
BorderPane.setAlignment(colorBox, Pos.CENTER);
|
||||
//sliderPane.setPadding(new Insets(10,0,0,0));
|
||||
BorderPane.setMargin(colorBox, new Insets(0,5,0,5));
|
||||
|
||||
this.setCenter(colourSlider);
|
||||
this.setRight(colorBox);
|
||||
|
||||
//set up so the correct color
|
||||
colorBox.setValue(ColourArray.getName(getColourArrayType()));
|
||||
colourSlider.setColourArrayType(getColourArrayType());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setDataStreamPanel(DataStreamPaneFX selectedItem) {
|
||||
this.dataStreamPane=selectedItem;
|
||||
//TODO - set the colours here.
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set colours depending on current colour selection in combo box.
|
||||
*/
|
||||
private void setColours(){
|
||||
this.setColourArrayType(ColourArray.getColourArrayType(colorBox.getValue()));
|
||||
colourSlider.setColourArrayType(getColourArrayType());
|
||||
}
|
||||
|
||||
|
||||
public ColourArrayType getColourArrayType() {
|
||||
return colorArray;
|
||||
}
|
||||
|
||||
public void setColourArrayType(ColourArrayType colourArrayType) {
|
||||
this.colorArray = colourArrayType;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a pane to change vertical scales.
|
||||
* @return pamne with controls to change vertical scales.
|
||||
*/
|
||||
private PamGridPane createScalePane() {
|
||||
|
||||
PamGridPane controlPane=new PamGridPane();
|
||||
controlPane.setHgap(5);
|
||||
controlPane.setVgap(5);
|
||||
|
||||
// //create time scale controls
|
||||
// controlPane.add(new Label("Time window"),0,1);
|
||||
//
|
||||
// //create time slider
|
||||
// timeSlider=new Slider(0, timeScaleChoices.length-1, 1);
|
||||
// timeSlider.setShowTickLabels(true);
|
||||
// timeSlider.setShowTickMarks(true);
|
||||
// timeSlider.setMajorTickUnit(1);
|
||||
//
|
||||
// timeSlider.setLabelFormatter(new ScaleStringConverter());
|
||||
//
|
||||
//// PamGridPane.setHalignment(timeSlider, Pos.BOTTOM_CENTER);
|
||||
//
|
||||
// controlPane.add(timeSlider,1,1);
|
||||
// //add listener to time slider to change datamap.
|
||||
// timeSlider.valueProperty().addListener((ov, oldVal, newVal)->{
|
||||
// sayHScale();
|
||||
// dataMapPane.scaleChanged();
|
||||
// });
|
||||
//
|
||||
// controlPane.add(timeScaleLabel=new Label(""),3,1);
|
||||
|
||||
//create vertical scale controls
|
||||
|
||||
scaleBox=new ComboBox<String> ();
|
||||
scaleBox.getItems().add("No Scaling");
|
||||
scaleBox.getItems().add("per Second");
|
||||
scaleBox.getItems().add("per Minute");
|
||||
scaleBox.getItems().add("per Hour");
|
||||
scaleBox.getItems().add("per Day");
|
||||
|
||||
controlPane.add(new Label("Show detections "),0,0);
|
||||
controlPane.add(scaleBox,1,0);
|
||||
// scaleBox.setPrefWidth(200);
|
||||
|
||||
scaleBox.valueProperty().addListener((ov, oldVal, newVal)->{
|
||||
dataMapPane.scaleChanged();
|
||||
});
|
||||
|
||||
|
||||
logScaleToggle=new PamToggleSwitch("Log Scale");
|
||||
logScaleToggle.selectedProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
dataMapPane.scaleChanged();
|
||||
});
|
||||
|
||||
|
||||
controlPane.add(logScaleToggle,0,1);
|
||||
|
||||
|
||||
return controlPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the horizontal scale.
|
||||
*/
|
||||
private void sayHScale() {
|
||||
// double hChoice = timeScaleChoices[this.];
|
||||
// timeScaleLabel.setText(String.format("%s pixs/hour", new Double(timeScaleChoices[(int) hChoice]).toString()));
|
||||
}
|
||||
|
||||
//HACK use setting flag to avoid immediate callback which overwrites changes 2 and 3 !
|
||||
boolean setting = false;
|
||||
|
||||
public void setParams(DataMapParameters dataMapParameters) {
|
||||
setting = true;
|
||||
// timeSlider.setValue(dataMapParameters.hScaleChoice);
|
||||
scaleBox.getSelectionModel().select(dataMapParameters.vScaleChoice);
|
||||
logScaleToggle.setSelected(dataMapParameters.vLogScale);
|
||||
|
||||
//make sure the combo box has correct datastreams
|
||||
updateDataStreamBox();
|
||||
|
||||
setting = false;
|
||||
}
|
||||
|
||||
|
||||
public DataMapParameters getParams(DataMapParameters dataMapParameters) {
|
||||
if (setting) return dataMapParameters;
|
||||
// dataMapParameters.hScaleChoice = (int) timeSlider.getValue();
|
||||
dataMapParameters.vScaleChoice = scaleBox.getSelectionModel().getSelectedIndex();
|
||||
dataMapParameters.vLogScale = logScaleToggle.isSelected();
|
||||
|
||||
return dataMapParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Datamap settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
// TODO Auto-generated method stub
|
||||
return mainPain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -138,6 +138,7 @@ public class DataStreamPaneFX extends PamBorderPane {
|
||||
dataGraph = new DataGraphFX();
|
||||
dataGraph.setupAxis();
|
||||
dataName = new DataName();
|
||||
dataName.setName(dataBlock.getDataName());
|
||||
|
||||
this.setTop(topPane=createTopPane());
|
||||
this.setCenter(dataGraph);
|
||||
@ -990,6 +991,16 @@ public class DataStreamPaneFX extends PamBorderPane {
|
||||
}
|
||||
|
||||
public class DataName {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String dataName) {
|
||||
this.name=dataName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,293 +0,0 @@
|
||||
package dataMap.layoutFX;
|
||||
|
||||
import dataGram.DatagramManager;
|
||||
import dataGram.DatagramSettings;
|
||||
import dataMap.DataMapControl;
|
||||
import dataMap.DataMapParameters;
|
||||
import PamController.PamController;
|
||||
import PamUtils.PamCalendar;
|
||||
import binaryFileStorage.BinaryStore;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.util.StringConverter;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxNodes.sliders.PamSlider;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
|
||||
/**
|
||||
* Allows uses to change the horizontal and vertical scales on the data map.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class ScalePaneFX extends PamBorderPane {
|
||||
|
||||
/*
|
||||
* Reference to the data map control.
|
||||
*/
|
||||
private DataMapControl dataMapControl;
|
||||
|
||||
/**
|
||||
* Reference to the dataMapPane.
|
||||
*/
|
||||
private DataMapPaneFX dataMapPane;
|
||||
|
||||
/**
|
||||
* The slider which determines time scale.
|
||||
*/
|
||||
private Slider timeSlider;
|
||||
|
||||
/**
|
||||
* Shows the time scale in pix/hour
|
||||
*/
|
||||
private Label timeScaleLabel;
|
||||
|
||||
/**
|
||||
* Selects unit count on vertical scale
|
||||
*/
|
||||
private ComboBox<String> scaleBox;
|
||||
|
||||
/**
|
||||
* Check box for log vertical scale.
|
||||
*/
|
||||
private PamToggleSwitch logScaleBox;
|
||||
|
||||
/**
|
||||
* The chosen time values.
|
||||
*/
|
||||
private double[] timeScaleChoices = DataMapParameters.hScaleChoices;
|
||||
|
||||
/**
|
||||
* Combo box holding options to channge the datargam bin size
|
||||
*/
|
||||
private ComboBox<String> datagramBox;
|
||||
|
||||
/**
|
||||
* Holds a list of times for the datagram bin size.
|
||||
*/
|
||||
private ComboBox<String> dataGramComboBox;
|
||||
|
||||
/**
|
||||
* Holds everything.
|
||||
*/
|
||||
private PamVBox holder;
|
||||
|
||||
/**
|
||||
* Grid pane with settings for the data scales
|
||||
*/
|
||||
private PamGridPane scaleSettingsPane;
|
||||
|
||||
private Label dataGramLabel;
|
||||
|
||||
|
||||
|
||||
public ScalePaneFX(DataMapControl dataMapControl, DataMapPaneFX dataMapPane) {
|
||||
this.dataMapControl = dataMapControl;
|
||||
this.dataMapPane = dataMapPane;
|
||||
|
||||
// //create the holder pane.
|
||||
// PamVBox vBoxHolder=new PamVBox();
|
||||
// vBoxHolder.setSpacing(5);
|
||||
// Label title=new Label("Scales");
|
||||
// PamGuiManagerFX.titleFont2style(title);
|
||||
// vBoxHolder.getChildren().addAll(title, controlPane);
|
||||
|
||||
holder=new PamVBox();
|
||||
holder.setSpacing(20);
|
||||
holder.getChildren().add(scaleSettingsPane = createScalePane());
|
||||
|
||||
this.setCenter(holder);
|
||||
|
||||
//set params for the pane
|
||||
setParams(dataMapControl.dataMapParameters);
|
||||
checkDataGramPane(); // create datagram pane if a binary store already added.
|
||||
sayHScale();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a settings pane for the datagram if a binary store is present.
|
||||
*/
|
||||
public void checkDataGramPane(){
|
||||
if (BinaryStore.findBinaryStoreControl()!=null){
|
||||
DatagramManager dataGramManager=BinaryStore.findBinaryStoreControl().getDatagramManager();
|
||||
if (dataGramManager!=null && datagramBox==null) {
|
||||
datagramBox=createDatagramPane(dataGramManager);
|
||||
scaleSettingsPane.add(dataGramLabel= new Label("Datagram bin size"), 0, 2);
|
||||
scaleSettingsPane.add(dataGramComboBox, 1, 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
scaleSettingsPane.getChildren().remove(dataGramLabel);
|
||||
scaleSettingsPane.getChildren().remove(dataGramComboBox);
|
||||
|
||||
datagramBox=null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the a datagram combo box to change the size of the datagram
|
||||
* @param dataGramManager - the datagram manager for the current biinary store.
|
||||
* @return a combo box with datagram bin sizes.
|
||||
*/
|
||||
private ComboBox<String> createDatagramPane(DatagramManager dataGramManager){
|
||||
|
||||
dataGramComboBox=new ComboBox<String>(createDurationList(dataGramManager));
|
||||
|
||||
dataGramComboBox.getSelectionModel().select(durationToString(dataGramManager.getDatagramSettings().datagramSeconds*1000L));
|
||||
dataGramComboBox.valueProperty().addListener(( ov, t, t1) -> {
|
||||
if (t==t1) return;
|
||||
else {
|
||||
PamController.getInstance();
|
||||
boolean ans=PamDialogFX.showWarning(PamController.getMainStage(), "Warning", "<html>Recalculating the datagram for a large dataset may take a long time<br>" +
|
||||
"Are you sure you want to continue ?</html>");
|
||||
if (ans){
|
||||
int index=dataGramComboBox.getSelectionModel().getSelectedIndex();
|
||||
//messy- datagramSeconfds should be in millis but left for backwards compatibility.
|
||||
dataGramManager.getDatagramSettings().datagramSeconds=(int) (DatagramSettings.defaultDatagramSeconds[index]/1000);
|
||||
dataGramManager.updateDatagrams();
|
||||
dataMapPane.repaintAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return dataGramComboBox;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert duration to string.
|
||||
* @param duration in millis.
|
||||
*/
|
||||
private String durationToString(long duration){
|
||||
return (" " + PamCalendar.formatDuration(duration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create list of load times.
|
||||
* @return list of load times duration.
|
||||
*/
|
||||
private ObservableList<String> createDurationList(DatagramManager dataGramManager){
|
||||
ObservableList<String> loadTimeList=FXCollections.observableArrayList();
|
||||
for (int i=0; i<DatagramSettings.defaultDatagramSeconds.length; i++){
|
||||
loadTimeList.add(durationToString(DatagramSettings.defaultDatagramSeconds[i]));
|
||||
}
|
||||
return loadTimeList;
|
||||
}
|
||||
|
||||
|
||||
private PamGridPane createScalePane() {
|
||||
|
||||
PamGridPane controlPane=new PamGridPane();
|
||||
controlPane.setHgap(5);
|
||||
controlPane.setVgap(5);
|
||||
|
||||
//create time scale controls
|
||||
controlPane.add(new Label("Time window"),0,1);
|
||||
|
||||
//create time slider
|
||||
timeSlider=new Slider(0, timeScaleChoices.length-1, 1);
|
||||
timeSlider.setShowTickLabels(true);
|
||||
timeSlider.setShowTickMarks(true);
|
||||
timeSlider.setMajorTickUnit(1);
|
||||
|
||||
timeSlider.setLabelFormatter(new ScaleStringConverter());
|
||||
|
||||
// PamGridPane.setHalignment(timeSlider, Pos.BOTTOM_CENTER);
|
||||
|
||||
controlPane.add(timeSlider,1,1);
|
||||
//add listener to time slider to change datamap.
|
||||
timeSlider.valueProperty().addListener((ov, oldVal, newVal)->{
|
||||
sayHScale();
|
||||
dataMapPane.scaleChanged();
|
||||
});
|
||||
|
||||
controlPane.add(timeScaleLabel=new Label(""),3,1);
|
||||
|
||||
//create vertical scale controls
|
||||
controlPane.add(new Label("Data counts"),0,0);
|
||||
|
||||
|
||||
scaleBox=new ComboBox<String> ();
|
||||
scaleBox.getItems().add("No Scaling");
|
||||
scaleBox.getItems().add("per Second");
|
||||
scaleBox.getItems().add("per Minute");
|
||||
scaleBox.getItems().add("per Hour");
|
||||
scaleBox.getItems().add("per Day");
|
||||
controlPane.add(scaleBox,1,0);
|
||||
scaleBox.setPrefWidth(200);
|
||||
|
||||
scaleBox.valueProperty().addListener((ov, oldVal, newVal)->{
|
||||
dataMapPane.scaleChanged();
|
||||
});
|
||||
|
||||
|
||||
logScaleBox=new PamToggleSwitch("Log Scale");
|
||||
logScaleBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
dataMapPane.scaleChanged();
|
||||
});
|
||||
|
||||
|
||||
controlPane.add(logScaleBox,3,0);
|
||||
|
||||
|
||||
return controlPane;
|
||||
}
|
||||
|
||||
class ScaleStringConverter extends StringConverter<Double> {
|
||||
|
||||
@Override
|
||||
public String toString(Double object) {
|
||||
return String.valueOf(timeScaleChoices[object.intValue()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double fromString(String string) {
|
||||
return Double.valueOf(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the horizontal scale.
|
||||
*/
|
||||
private void sayHScale() {
|
||||
double hChoice = timeSlider.getValue();
|
||||
timeScaleLabel.setText(String.format("%s pixs/hour", new Double(timeScaleChoices[(int) hChoice]).toString()));
|
||||
}
|
||||
|
||||
//HACK use setting flag to avoid immediate callback which overwrites changes 2 and 3 !
|
||||
boolean setting = false;
|
||||
|
||||
public void setParams(DataMapParameters dataMapParameters) {
|
||||
setting = true;
|
||||
timeSlider.setValue(dataMapParameters.hScaleChoice);
|
||||
scaleBox.getSelectionModel().select(dataMapParameters.vScaleChoice);
|
||||
logScaleBox.setSelected(dataMapParameters.vLogScale);
|
||||
setting = false;
|
||||
}
|
||||
|
||||
|
||||
public void getParams(DataMapParameters dataMapParameters) {
|
||||
if (setting) return;
|
||||
dataMapParameters.hScaleChoice = (int) timeSlider.getValue();
|
||||
dataMapParameters.vScaleChoice = scaleBox.getSelectionModel().getSelectedIndex();
|
||||
dataMapParameters.vLogScale = logScaleBox.isSelected();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
|
||||
|
||||
/**
|
||||
* Standard millis to wait for repaint.
|
||||
* Do not ake this too high i.e. above 50 or the display gets very jerky
|
||||
* Do not make this too high i.e. above 50 or the display gets very jerky
|
||||
*/
|
||||
public static final long REPAINTMILLIS = 50;
|
||||
|
||||
@ -496,4 +496,24 @@ public class ScrollingDataPaneFX extends PamBorderPane {
|
||||
// this.notifyScrollChange();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the current number of data stream panes
|
||||
* @return the number of data stream panes
|
||||
*/
|
||||
public int getNumDataStreamPanes() {
|
||||
return this.dataStreamPanels.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a data stream pane.
|
||||
* @param n - the index of the data stream pane
|
||||
* @return the data stream pane or null if the index is out of bounds.
|
||||
*/
|
||||
public DataStreamPaneFX getDataSyreamPane(int n) {
|
||||
if (n<this.dataStreamPanels.size()) {
|
||||
return dataStreamPanels.get(n);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,16 +7,13 @@ import PamView.paneloverlay.overlaymark.OverlayMark;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.PamRawDataBlock;
|
||||
import detectiongrouplocaliser.DetectionGroupSummary;
|
||||
import export.wavExport.WavFileExportManager;
|
||||
import javafx.animation.Timeline;
|
||||
import export.wavExport.WavDetExport;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.Labeled;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.effect.ColorInput;
|
||||
import javafx.scene.text.Text;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import wavFiles.WavFileWriter;
|
||||
|
||||
/**
|
||||
* Export a .wav clip.
|
||||
@ -27,27 +24,27 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
|
||||
|
||||
private Text wavFileGlyph;
|
||||
|
||||
/**
|
||||
* The wav file write
|
||||
*/
|
||||
private WavFileWriter wavFile;
|
||||
// /**
|
||||
// * The wav file write
|
||||
// */
|
||||
// private WavFileWriter wavFile;
|
||||
//
|
||||
// private String defaultPath;
|
||||
//
|
||||
// private String currentFolder;
|
||||
|
||||
private String defaultPath;
|
||||
private WavDetExport wavExportManager;
|
||||
|
||||
private String currentFolder;
|
||||
|
||||
private WavFileExportManager wavExportManager;
|
||||
|
||||
private ColorInput shadow;
|
||||
|
||||
private Timeline timline;
|
||||
// private ColorInput shadow;
|
||||
//
|
||||
// private Timeline timline;
|
||||
|
||||
private PamButton pamButton;
|
||||
|
||||
public WavExportOverlayMenu(){
|
||||
// wavFileGlyph=PamGlyphDude.createPamGlyph(MaterialDesignIcon.FILE_MUSIC, standardIconSize);
|
||||
wavFileGlyph=PamGlyphDude.createPamIcon("mdi2f-file-music", standardIconSize+14);
|
||||
wavExportManager= new WavFileExportManager();
|
||||
wavExportManager= new WavDetExport();
|
||||
|
||||
//set a callback when saving is finsihed.
|
||||
wavExportManager.setOnWavSaved((saveFile, flag)->{
|
||||
@ -132,7 +129,7 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
|
||||
*/
|
||||
private void writeWavFile(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
|
||||
// animateButton() ; //start button animation.
|
||||
wavExportManager.dataUnits2Wav(foundDataUnits, selectedIndex, mark);
|
||||
wavExportManager.writeOverlayMarkWav(foundDataUnits, selectedIndex, mark);
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +145,7 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
|
||||
rawDataBlock=foundDataUnits.getDataList().get(0).getParentDataBlock().getRawSourceDataBlock();
|
||||
}
|
||||
//is there available raw data
|
||||
if (mark!=null && WavFileExportManager.haveRawData(rawDataBlock, (long) mark.getLimits()[0], (long) mark.getLimits()[1])) {
|
||||
if (mark!=null && WavDetExport.haveRawData(rawDataBlock, (long) mark.getLimits()[0], (long) mark.getLimits()[1])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import dataPlotsFX.layout.TDGraphFX.TDPlotPane;
|
||||
import dataPlotsFX.overlaymark.menuOptions.OverlayMenuItem;
|
||||
import dataPlotsFX.overlaymark.menuOptions.OverlayMenuManager;
|
||||
import detectiongrouplocaliser.DetectionGroupSummary;
|
||||
import export.wavExport.WavFileExportManager;
|
||||
import export.wavExport.WavDetExport;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
@ -546,7 +546,7 @@ public class TDMenuPane extends PamBorderPane {
|
||||
PamRawDataBlock pamRawBlock = findRawSourceBlock();
|
||||
// System.out.println("Pam raw data block: " + pamRawBlock);
|
||||
|
||||
if (WavFileExportManager.haveRawData(pamRawBlock, (long) overlayMarker.getCurrentMark().getLimits()[0], (long) overlayMarker.getCurrentMark().getLimits()[1])) {
|
||||
if (WavDetExport.haveRawData(pamRawBlock, (long) overlayMarker.getCurrentMark().getLimits()[0], (long) overlayMarker.getCurrentMark().getLimits()[1])) {
|
||||
//System.out.println("Overaly Marker start X: " + overlayMarker.getCurrentMark().getLimits()[0] + " end: " + overlayMarker.getCurrentMark().getLimits()[1]);
|
||||
//System.out.println("Overlay Marker start Y: " + overlayMarker.getCurrentMark().getLimits()[2] + " end: " + overlayMarker.getCurrentMark().getLimits()[3]);
|
||||
groupDetectionDisplay.showRawData(pamRawBlock, overlayMarker.getCurrentMark().getLimits(), overlayMarker.getCurrentMark().getMarkChannels());
|
||||
|
@ -925,6 +925,8 @@ public class Scrolling2DPlotDataFX {
|
||||
|
||||
//reset transform in case of other drawings on base canvas.
|
||||
if (orientation == Orientation.VERTICAL) g2d.setTransform(horzAffine);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,13 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* A general pane with a frequency slider, colour bar slider and colour combo box. These nodes are interconnected so when colour combo box is changed colours change.
|
||||
* Other than that this pane does nothing but all slider value properties are available to be used in another class or subclass. This means this control pane should be
|
||||
* available to be used for any spectrogram/3D colour image.
|
||||
* A general pane with a frequency slider, colour bar slider and colour combo
|
||||
* box. These nodes are interconnected so when colour combo box is changed
|
||||
* colours change. Other than that this pane does nothing but all slider value
|
||||
* properties are available to be used in another class or subclass. This means
|
||||
* this control pane should be available to be used for any spectrogram/3D
|
||||
* colour image.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
|
@ -48,8 +48,12 @@ public abstract class MLDataUnitExport<T extends PamDataUnit<?, ?>> {
|
||||
//UID for the detection.
|
||||
Matrix UID = Mat5.newScalar(dataUnit.getUID());
|
||||
|
||||
//the start sample.
|
||||
Matrix startSample = Mat5.newScalar(dataUnit.getStartSample());
|
||||
Matrix startSample = Mat5.newScalar(0);
|
||||
if (dataUnit.getStartSample()!=null) {
|
||||
//the start sample.
|
||||
startSample = Mat5.newScalar(dataUnit.getStartSample());
|
||||
}
|
||||
|
||||
|
||||
//the duration of the detection in samples.
|
||||
Matrix sampleDuration = Mat5.newScalar(dataUnit.getSampleDuration());
|
||||
|
@ -11,7 +11,7 @@ import PamguardMVC.PamDataUnit;
|
||||
import export.CSVExport.CSVExportManager;
|
||||
import export.MLExport.MLDetectionsManager;
|
||||
import export.RExport.RExportManager;
|
||||
import export.wavExport.WavFileExportManager;
|
||||
import export.wavExport.WavDetExportManager;
|
||||
|
||||
/**
|
||||
* Exports data to external files. Manages the file sizes and creates data buffers for
|
||||
@ -61,7 +61,7 @@ public class PamExporterManager {
|
||||
//add the MATLAB export
|
||||
pamExporters.add(new MLDetectionsManager());
|
||||
pamExporters.add(new RExportManager(this));
|
||||
pamExporters.add(new WavFileExportManager());
|
||||
pamExporters.add(new WavDetExportManager());
|
||||
// pamExporters.add(new CSVExportManager());
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ import PamguardMVC.PamDataBlock;
|
||||
import export.ExportParams;
|
||||
import export.PamExporterManager;
|
||||
import offlineProcessing.OLProcessDialog;
|
||||
import offlineProcessing.OLProcessDialog.OLMonitor;
|
||||
import offlineProcessing.OfflineTaskGroup;
|
||||
import offlineProcessing.TaskMonitor;
|
||||
import offlineProcessing.TaskMonitorData;
|
||||
@ -359,7 +360,7 @@ public class ExportProcessDialog {
|
||||
|
||||
|
||||
public void setParams(ExportParams params) {
|
||||
System.out.println("EXPORT: SET PARAMS: " +params);
|
||||
// System.out.println("EXPORT: SET PARAMS: " +params);
|
||||
|
||||
if (params ==null) currentParams = new ExportParams();
|
||||
currentParams = params.clone();
|
||||
@ -367,46 +368,87 @@ public class ExportProcessDialog {
|
||||
buttonGroup.clearSelection();
|
||||
exportButtons[params.exportChoice].setSelected(true);
|
||||
|
||||
System.out.println("EXPORT: SET PARAMS: " +currentParams.folder);
|
||||
// System.out.println("EXPORT: SET PARAMS: " +currentParams.folder);
|
||||
exportTo.setText(currentParams.folder);
|
||||
|
||||
spinner.setValue(currentParams.maximumFileSize);
|
||||
|
||||
enableTasks();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ok, this is a bit of a hack but because we run tasks for multiple data blocks
|
||||
* we have to run a new task whenever the previous task is finished. So we use a task monitor
|
||||
* to deetct when the task is finsihed and then, instead of finishing we run a new task.
|
||||
*/
|
||||
class ExportTaskMonitor extends OLMonitor {
|
||||
|
||||
private int taskIndex;
|
||||
|
||||
private ExportTaskGroup exportTaskGroup;
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
private int activeTasks;
|
||||
|
||||
public ExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
|
||||
super();
|
||||
this.taskIndex = i;
|
||||
this.exportTaskGroup = exportTaskGroup;
|
||||
|
||||
this.activeTasks = 0;
|
||||
for (int i1=0; i1<exportTaskGroup.getNTasks(); i1++) {
|
||||
if (exportTaskGroup.getTask(i1).isDoRun()) {
|
||||
activeTasks++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class ExportTaskMonitor implements TaskMonitor {
|
||||
|
||||
private int taskIndex;
|
||||
|
||||
private ExportTaskGroup exportTaskGroup;
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
public ExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
|
||||
this.taskIndex = i;
|
||||
this.exportTaskGroup = exportTaskGroup;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setTaskStatus(TaskMonitorData taskMonitorData) {
|
||||
if (taskMonitorData.taskStatus== TaskStatus.COMPLETE && !started) {
|
||||
System.out.println(" TASK COMPLETE:");
|
||||
if (taskIndex<exportTaskGroup.getNTasks()) {
|
||||
exportTaskGroup.runTaskFrom(taskIndex+1);
|
||||
started = true;
|
||||
@Override
|
||||
public void setTaskStatus(TaskMonitorData taskMonitorData) {
|
||||
|
||||
switch (taskMonitorData.taskStatus) {
|
||||
case COMPLETE:
|
||||
if (taskIndex<exportTaskGroup.getNTasks() && !started) {
|
||||
exportTaskGroup.runTaskFrom(taskIndex+1);
|
||||
started = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.setTaskStatus(taskMonitorData);
|
||||
}
|
||||
|
||||
//A hack which sets the global
|
||||
switch (taskMonitorData.taskActivity) {
|
||||
case LINKING:
|
||||
case LOADING:
|
||||
|
||||
//the progress of one datablocks
|
||||
double progress = ((double) taskMonitorData.progValue)/taskMonitorData.progMaximum;
|
||||
double totalProgress = ((double) taskIndex)/activeTasks + progress/activeTasks;
|
||||
// System.out.println("Total progress: " + taskMonitorData.progValue + " of " + taskMonitorData.progMaximum + " - " + totalProgress + "%" + " " + progress + " " + activeTasks + " " + taskIndex);
|
||||
//needs to be added to the overall progress
|
||||
int max = getGlobalProgress().getMaximum();
|
||||
getGlobalProgress().setValue((int) (totalProgress*max));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ExportTaskMonitor newExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
|
||||
return new ExportTaskMonitor(i, exportTaskGroup);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Export task
|
||||
*/
|
||||
@ -428,12 +470,12 @@ public class ExportProcessDialog {
|
||||
* @param i - the index
|
||||
*/
|
||||
public void runTaskFrom(int i) {
|
||||
System.out.println("RUN TASK FROM :" + i);
|
||||
|
||||
//sets the porimary datablock to that of the relevent task.
|
||||
this.setPrimaryDataBlock(getTask(i).getDataBlock());
|
||||
if (i<getNTasks()-1) {
|
||||
//will start a new thread after this one has finished
|
||||
this.setTaskMonitor(new ExportTaskMonitor(i, this));
|
||||
this.setTaskMonitor(mtOfflineDialog.newExportTaskMonitor(i, this));
|
||||
}
|
||||
super.runTasks();
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
|
||||
//System.out.println("Data selector null: " + this.getDataBlock().getDataName() + " " + dataUnit);
|
||||
exporter.exportDataUnit(dataUnit, false);
|
||||
}
|
||||
else if (dataSelector.scoreData(dataUnit)>0 && dataSelector.getParams().getCombinationFlag() != DataSelectParams.DATA_SELECT_DISABLE) {
|
||||
else if (dataSelector.scoreData(dataUnit)>0 || dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) {
|
||||
//System.out.println("Data selector OK: " + this.getDataBlock().getDataName() + " " + dataUnit);
|
||||
exporter.exportDataUnit(dataUnit, false);
|
||||
}
|
||||
@ -73,7 +73,7 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
|
||||
|
||||
@Override
|
||||
public void loadedDataComplete() {
|
||||
System.out.println("EXPORTER: loaded data complete");
|
||||
// System.out.println("EXPORTER: loaded data complete");
|
||||
//force the exporter so save any renaming data units in the buffer
|
||||
exporter.exportDataUnit(null, true);
|
||||
exporter.close();
|
||||
|
@ -1,6 +1,5 @@
|
||||
package export.wavExport;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -20,46 +19,36 @@ import PamguardMVC.PamObservable;
|
||||
import PamguardMVC.PamObserver;
|
||||
import PamguardMVC.PamObserverAdapter;
|
||||
import PamguardMVC.PamRawDataBlock;
|
||||
import PamguardMVC.RawDataHolder;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoading;
|
||||
import dataMap.OfflineDataMapPoint;
|
||||
import detectiongrouplocaliser.DetectionGroupSummary;
|
||||
import export.PamDataUnitExporter;
|
||||
import javafx.scene.layout.Pane;
|
||||
import wavFiles.Wav16AudioFormat;
|
||||
import wavFiles.WavFileWriter;
|
||||
|
||||
/**
|
||||
* Manages .wav file writing based on what type of data unit is selected and whether raw data is available.
|
||||
* <p>
|
||||
* There are two primary use cases;
|
||||
* <br>
|
||||
* 1) Order raw data from an overlay mark and save as a wav file
|
||||
* <br>
|
||||
* 2) Save a list of data units to wav files - either a single file with zero pads, a concatonated file or seperate files.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class WavFileExportManager implements PamDataUnitExporter {
|
||||
|
||||
public class WavDetExport {
|
||||
|
||||
/**
|
||||
* Successful writing of .wav file.
|
||||
*/
|
||||
public static final int SUCCESS_WAV=0;
|
||||
// public static final int SUCCESS_WAV=0;
|
||||
|
||||
/**
|
||||
* Successful writing of .wav file from data contained in detections.
|
||||
*/
|
||||
public static final int SUCCESS_DET_WAV=1;
|
||||
// public static final int SUCCESS_DET_WAV=1;
|
||||
|
||||
/**
|
||||
* General failure in wav file writing
|
||||
*/
|
||||
public static final int FAILURE_WAV=2;
|
||||
// public static final int FAILURE_WAV=2;
|
||||
|
||||
|
||||
public static final int LOADING_WAV=2;
|
||||
// public static final int LOADING_WAV=2;
|
||||
|
||||
/**
|
||||
* The maximum allowed size
|
||||
*/
|
||||
private static final double MAX_ZEROPAD_SIZE_MEGABYTES = 1024; //MB
|
||||
|
||||
/**
|
||||
* The default path to write files to
|
||||
@ -80,7 +69,7 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
|
||||
private WavOptionsPanel wavOptionsPanel;
|
||||
|
||||
public WavFileExportManager() {
|
||||
public WavDetExport() {
|
||||
wavDataUnitExports.add(new RawHolderWavExport());
|
||||
|
||||
defaultPath=FileSystemView.getFileSystemView().getDefaultDirectory().getPath();
|
||||
@ -179,7 +168,7 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
* @param selectedIndex - the currently selected data unit.
|
||||
* @param mark - overlay mark.
|
||||
*/
|
||||
public int dataUnits2Wav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
|
||||
public int writeOverlayMarkWav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
|
||||
System.out.println("Data units 2 wav");
|
||||
//this order for .wav files.
|
||||
//if there is a mark then save limits of mark. If there is one data unit then set limits of data units
|
||||
@ -224,15 +213,18 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
|
||||
int flag=-1;
|
||||
|
||||
String currentFileS = createFileName(foundDataUnits.getFirstTimeMillis());
|
||||
File file = new File(currentFileS);
|
||||
|
||||
if (hasAllWavClips) {
|
||||
flag = saveDataUnitWav(foundDataUnits);
|
||||
flag = writeDetGroupWav(foundDataUnits, file, false);
|
||||
}
|
||||
else if (!hasAllWavClips && haveRawData) {
|
||||
//no raw data
|
||||
flag = saveRawWav(start, end, rawDataBlock);
|
||||
}
|
||||
else {
|
||||
flag = saveDataUnitWav(foundDataUnits);
|
||||
flag = writeDetGroupWav(foundDataUnits, file, false);
|
||||
}
|
||||
|
||||
return flag;
|
||||
@ -263,47 +255,129 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
/**
|
||||
* Save wav data from a data unit instead of from the raw file store.
|
||||
* @param foundDataUnits - the list of found data units.
|
||||
* @param currentFile - path to current file to save to.
|
||||
* @param zeroPad - if true will zeroPad detections.
|
||||
* @return the number of data units that were saved.
|
||||
*/
|
||||
private int saveDataUnitWav(DetectionGroupSummary foundDataUnits) {
|
||||
return saveDataUnitWav(foundDataUnits.getDataList());
|
||||
public int writeDetGroupWav(DetectionGroupSummary foundDataUnits, File filename, boolean zeroPad) {
|
||||
return writeDataUnitWav(foundDataUnits.getDataList(), filename, zeroPad);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save data units which contain raw data to a wav file. Note that this assumed
|
||||
* the data units all contain raw data and are in order.
|
||||
*
|
||||
* @param foundDataUnits - data units containing raw data.
|
||||
* @return the number of data units saved - this should be the same as the size
|
||||
* of the data unit list.
|
||||
* Save data units which contain raw data to individual wav files within a folder.
|
||||
* @param foundDataUnits - list of data units to save.
|
||||
* @param currentFile - the current folder. If this is a file name the parent directory will be used.
|
||||
* @return the number of data units saved
|
||||
*/
|
||||
private int saveDataUnitWav(List<PamDataUnit> foundDataUnits) {
|
||||
public int writeDataUnitWavs(List<PamDataUnit> foundDataUnits, File currentFile) {
|
||||
int n=0;
|
||||
WavFileWriter wavWrite = null;
|
||||
for (PamDataUnit fnDataUnit: foundDataUnits){
|
||||
|
||||
String currentFile = createFileName(fnDataUnit.getTimeMilliseconds());
|
||||
|
||||
|
||||
AudioFormat audioFormat = new Wav16AudioFormat(fnDataUnit.getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(fnDataUnit.getChannelBitmap()));
|
||||
|
||||
System.out.println("Save detection wav." + foundDataUnits.size());
|
||||
|
||||
String currentFileS = createFileName(fnDataUnit.getTimeMilliseconds());
|
||||
|
||||
//System.out.println("Save detection wav." + foundDataUnits.size());
|
||||
for (int i=0; i<wavDataUnitExports.size(); i++) {
|
||||
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
|
||||
|
||||
wavWrite= new WavFileWriter(currentFile, audioFormat);
|
||||
wavWrite= new WavFileWriter(currentFileS, audioFormat);
|
||||
|
||||
System.out.println("Append wav." + foundDataUnits.size());
|
||||
System.out.println("Write individual wav." + foundDataUnits.size());
|
||||
//save the wav file of detection
|
||||
wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit));
|
||||
n++;
|
||||
|
||||
wavWrite.close();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data units which contain raw data to a wav file. Note that this assumed
|
||||
* the data units all contain raw data, the raw data is at the same sample rate and number of channels
|
||||
* and the data units are in order. This will APPEND to the wav file if it currently exists.
|
||||
*
|
||||
* @param foundDataUnits - data units containing raw data.
|
||||
* @param currentFile - path to current file to save to.
|
||||
* @param zeroPad - if true will zeroPad detections.
|
||||
* @return the number of data units saved - this should be the same as the size
|
||||
* of the data unit list.
|
||||
*/
|
||||
public int writeDataUnitWav(List<PamDataUnit> foundDataUnits, File currentFile, boolean zeroPad) {
|
||||
int n=0;
|
||||
WavFileWriter wavWrite = null;
|
||||
PamDataUnit lastfnDataUnit = null;
|
||||
|
||||
if (foundDataUnits==null || foundDataUnits.size()<=0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//System.out.println("Save detection wav." + foundDataUnits.size());
|
||||
AudioFormat audioFormat = new Wav16AudioFormat(foundDataUnits.get(0).getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(foundDataUnits.get(0).getChannelBitmap()));
|
||||
|
||||
wavWrite= new WavFileWriter(currentFile.getAbsolutePath(), audioFormat);
|
||||
|
||||
for (PamDataUnit fnDataUnit: foundDataUnits){
|
||||
|
||||
for (int i=0; i<wavDataUnitExports.size(); i++) {
|
||||
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
|
||||
|
||||
System.out.println("Append wav. data unit: " + n + " samples: " + wavDataUnitExports.get(i).getWavClip(fnDataUnit)[0].length + " zeroPad: " + zeroPad);
|
||||
|
||||
if (zeroPad && lastfnDataUnit!=null) {
|
||||
//we need to append zero samples between the detections.
|
||||
long timeMillisDiff = fnDataUnit.getTimeMilliseconds() - lastfnDataUnit.getTimeMilliseconds();
|
||||
|
||||
long sampleDiff = fnDataUnit.getStartSample() - lastfnDataUnit.getStartSample();
|
||||
|
||||
int samplesPad;
|
||||
//are the two similar? - are they within 5 milliseconds
|
||||
if (Math.abs(((sampleDiff/audioFormat.getSampleRate())*1000.) - timeMillisDiff)<5){
|
||||
//use the sample diff
|
||||
samplesPad = (int) sampleDiff;
|
||||
}
|
||||
else {
|
||||
//use time millis for padding. May indicate that data units are from different wav files.
|
||||
samplesPad = (int) ((((double) timeMillisDiff)/1000.)*audioFormat.getSampleRate());
|
||||
}
|
||||
|
||||
//now safety check - is this more than one GB of data. Each sample is 16bits but the input double array is 64 bits each.
|
||||
double size = samplesPad*16*audioFormat.getChannels()/1024/1024;
|
||||
|
||||
//
|
||||
if (size>MAX_ZEROPAD_SIZE_MEGABYTES) {
|
||||
wavWrite.close();
|
||||
System.err.println(String.format("WavExportManager: A zero padding of %.2f MB was requested. The maximum allowed size is %.2f - "
|
||||
+ "the .wav file was closed and any additional data units have not been written %s", size, MAX_ZEROPAD_SIZE_MEGABYTES, currentFile));
|
||||
return n;
|
||||
}
|
||||
|
||||
System.out.println("Append wav. zero pad" + samplesPad);
|
||||
|
||||
wavWrite.append(new double[audioFormat.getChannels()][samplesPad]);
|
||||
}
|
||||
|
||||
//save the wav file of detection
|
||||
if (wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit))) {
|
||||
n++;
|
||||
}
|
||||
lastfnDataUnit = fnDataUnit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wavWrite.close();
|
||||
|
||||
|
||||
//send a message that the wav file has saved
|
||||
if (wavWrite!=null && saveCallback!=null) saveCallback.wavSaved(wavWrite.getFileName(), 0);
|
||||
|
||||
@ -340,85 +414,6 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasCompatibleUnits(Class dataUnitType) {
|
||||
// boolean implementsInterface = Arrays.stream(dataUnitType.getInterfaces()).anyMatch(i -> i == RawDataHolder.class);
|
||||
if ( RawDataHolder.class.isAssignableFrom(dataUnitType)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean exportData(File fileName,
|
||||
List<PamDataUnit> dataUnits, boolean append) {
|
||||
|
||||
|
||||
//should we zeropad?
|
||||
saveDataUnitWav(dataUnits);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getFileExtension() {
|
||||
return "wav";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getIconString() {
|
||||
return "mdi2f-file-music";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "raw sound";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isNeedsNewFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Component getOptionsPanel() {
|
||||
if (this.wavOptionsPanel==null) {
|
||||
this.wavOptionsPanel = new WavOptionsPanel();
|
||||
}
|
||||
return wavOptionsPanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Pane getOptionsPane() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Observes incoming raw data and saves to a wav file
|
||||
*
|
||||
@ -528,70 +523,4 @@ public class WavFileExportManager implements PamDataUnitExporter {
|
||||
}
|
||||
|
||||
|
||||
// hello(){
|
||||
//
|
||||
//
|
||||
// if (mark==null) {
|
||||
// start= foundDataUnits.getFirstTimeMillis();
|
||||
// end= foundDataUnits.getLastTimeMillis();
|
||||
// }
|
||||
//
|
||||
// File folder = new File(currentFolder);
|
||||
//
|
||||
// //save a .wav file clip.
|
||||
// if (!folder.exists()){
|
||||
// if (!folder.mkdir()){
|
||||
// //TODO- warning message.
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// String currentPath = PamCalendar.formatFileDateTime();
|
||||
// //add data types to the filen,ae
|
||||
// for (int i=0 ;i<mlData.size(); i++ ){
|
||||
// currentPath=currentPath + "_" + mlData.get(i).getName();
|
||||
// }
|
||||
// //add correct file type.
|
||||
// currentPath = currentPath + ".mat";
|
||||
// currentPath = currentFolder+"\\"+currentPath;
|
||||
//
|
||||
//
|
||||
// if (append && clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
|
||||
// wavFile.append(rawData);
|
||||
// lastClipDataUnit.setSampleDuration(rawEnd-lastClipDataUnit.getStartSample());
|
||||
// clipDataBlock.updatePamData(lastClipDataUnit, dataUnit.getTimeMilliseconds());
|
||||
// // System.out.println(String.format("%d samples added to file", rawData[0].length));
|
||||
// }
|
||||
// else {
|
||||
// ClipDataUnit clipDataUnit;
|
||||
// long startMillis = dataUnit.getTimeMilliseconds() - (long) (clipGenSetting.preSeconds*1000.);
|
||||
// if (clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
|
||||
// String folderName = getClipFileFolder(dataUnit.getTimeMilliseconds(), true);
|
||||
// String fileName = getClipFileName(startMillis);
|
||||
// AudioFormat af = new Wav16AudioFormat(getSampleRate(), rawData.length);
|
||||
// wavFile = new WavFileWriter(folderName+fileName, af);
|
||||
// wavFile.write(rawData);
|
||||
// wavFile.close();
|
||||
// // make a data unit to go with it.
|
||||
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
|
||||
// (int)(rawEnd-rawStart), channelMap, fileName, dataBlock.getDataName(), rawData, getSampleRate());
|
||||
// }
|
||||
// else {
|
||||
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
|
||||
// (int)(rawEnd-rawStart), channelMap, "", dataBlock.getDataName(), rawData, getSampleRate());
|
||||
// }
|
||||
// clipDataUnit.setFrequency(dataUnit.getFrequency());
|
||||
// lastClipDataUnit = clipDataUnit;
|
||||
// if (bearingLocaliser != null) {
|
||||
// localiseClip(clipDataUnit, bearingLocaliser, hydrophoneMap);
|
||||
// }
|
||||
// clipDataBlock.addPamData(clipDataUnit);
|
||||
// }
|
||||
//
|
||||
// return 0; // no error.
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
229
src/export/wavExport/WavDetExportManager.java
Normal file
229
src/export/wavExport/WavDetExportManager.java
Normal file
@ -0,0 +1,229 @@
|
||||
package export.wavExport;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.PamUtils;
|
||||
import PamView.paneloverlay.overlaymark.OverlayMark;
|
||||
import PamguardMVC.LoadObserver;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.PamObservable;
|
||||
import PamguardMVC.PamObserver;
|
||||
import PamguardMVC.PamObserverAdapter;
|
||||
import PamguardMVC.PamRawDataBlock;
|
||||
import PamguardMVC.RawDataHolder;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoading;
|
||||
import dataMap.OfflineDataMapPoint;
|
||||
import detectiongrouplocaliser.DetectionGroupSummary;
|
||||
import export.PamDataUnitExporter;
|
||||
import javafx.scene.layout.Pane;
|
||||
import wavFiles.Wav16AudioFormat;
|
||||
import wavFiles.WavFileWriter;
|
||||
|
||||
/**
|
||||
* Writes data units and/or ordered raw data to a wav file. Has functions to
|
||||
* handle .wav file writing based on overlay marks and detection groups with
|
||||
* functions to make decisions based on what type of data unit is selected and
|
||||
* whether raw data is available.
|
||||
* <p>
|
||||
* There are two primary use cases; <br>
|
||||
* 1) Order raw data from an overlay mark and save as a wav file <br>
|
||||
* 2) Save a list of data units to wav files - either a single file with zero
|
||||
* pads, a concatenated file or separate files.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class WavDetExportManager implements PamDataUnitExporter {
|
||||
|
||||
/**
|
||||
* Options for exporting wav files.
|
||||
*/
|
||||
private WavExportOptions wavFileoptions = new WavExportOptions();
|
||||
|
||||
/**
|
||||
* Settings panel for wav file exporting
|
||||
*/
|
||||
private WavOptionsPanel wavOptionsPanel;
|
||||
|
||||
/**
|
||||
* Exporter of wav files.
|
||||
*/
|
||||
private WavDetExport wavDetExport = new WavDetExport();
|
||||
|
||||
public WavDetExportManager() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCompatibleUnits(Class dataUnitType) {
|
||||
// boolean implementsInterface = Arrays.stream(dataUnitType.getInterfaces()).anyMatch(i -> i == RawDataHolder.class);
|
||||
if ( RawDataHolder.class.isAssignableFrom(dataUnitType)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean exportData(File fileName,
|
||||
List<PamDataUnit> dataUnits, boolean append) {
|
||||
|
||||
//make sure we have the latest options.
|
||||
if (wavOptionsPanel!=null) {
|
||||
//means the options panel has been opened.
|
||||
wavFileoptions = wavOptionsPanel.getParams(wavFileoptions);
|
||||
}
|
||||
|
||||
//should we zeropad?
|
||||
//saveDataUnitWav(dataUnits);
|
||||
switch (wavFileoptions.wavSaveChoice) {
|
||||
case WavExportOptions.SAVEWAV_CONCAT:
|
||||
wavDetExport.writeDataUnitWav(dataUnits, fileName, false);
|
||||
break;
|
||||
case WavExportOptions.SAVEWAV_INDIVIDUAL:
|
||||
//here the filename will not be used but the parent folder will be used instead to write
|
||||
//lots of wav files to.
|
||||
wavDetExport.writeDataUnitWavs(dataUnits, fileName);
|
||||
break;
|
||||
case WavExportOptions.SAVEWAV_ZERO_PAD:
|
||||
wavDetExport.writeDataUnitWav(dataUnits, fileName, true);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getFileExtension() {
|
||||
return "wav";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getIconString() {
|
||||
return "mdi2f-file-music";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "raw sound";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isNeedsNewFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Component getOptionsPanel() {
|
||||
if (this.wavOptionsPanel==null) {
|
||||
this.wavOptionsPanel = new WavOptionsPanel();
|
||||
}
|
||||
wavOptionsPanel.setParams(this.wavFileoptions) ;
|
||||
return wavOptionsPanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Pane getOptionsPane() {
|
||||
// TODO - make FX version of settings.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// hello(){
|
||||
//
|
||||
//
|
||||
// if (mark==null) {
|
||||
// start= foundDataUnits.getFirstTimeMillis();
|
||||
// end= foundDataUnits.getLastTimeMillis();
|
||||
// }
|
||||
//
|
||||
// File folder = new File(currentFolder);
|
||||
//
|
||||
// //save a .wav file clip.
|
||||
// if (!folder.exists()){
|
||||
// if (!folder.mkdir()){
|
||||
// //TODO- warning message.
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// String currentPath = PamCalendar.formatFileDateTime();
|
||||
// //add data types to the filen,ae
|
||||
// for (int i=0 ;i<mlData.size(); i++ ){
|
||||
// currentPath=currentPath + "_" + mlData.get(i).getName();
|
||||
// }
|
||||
// //add correct file type.
|
||||
// currentPath = currentPath + ".mat";
|
||||
// currentPath = currentFolder+"\\"+currentPath;
|
||||
//
|
||||
//
|
||||
// if (append && clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
|
||||
// wavFile.append(rawData);
|
||||
// lastClipDataUnit.setSampleDuration(rawEnd-lastClipDataUnit.getStartSample());
|
||||
// clipDataBlock.updatePamData(lastClipDataUnit, dataUnit.getTimeMilliseconds());
|
||||
// // System.out.println(String.format("%d samples added to file", rawData[0].length));
|
||||
// }
|
||||
// else {
|
||||
// ClipDataUnit clipDataUnit;
|
||||
// long startMillis = dataUnit.getTimeMilliseconds() - (long) (clipGenSetting.preSeconds*1000.);
|
||||
// if (clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
|
||||
// String folderName = getClipFileFolder(dataUnit.getTimeMilliseconds(), true);
|
||||
// String fileName = getClipFileName(startMillis);
|
||||
// AudioFormat af = new Wav16AudioFormat(getSampleRate(), rawData.length);
|
||||
// wavFile = new WavFileWriter(folderName+fileName, af);
|
||||
// wavFile.write(rawData);
|
||||
// wavFile.close();
|
||||
// // make a data unit to go with it.
|
||||
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
|
||||
// (int)(rawEnd-rawStart), channelMap, fileName, dataBlock.getDataName(), rawData, getSampleRate());
|
||||
// }
|
||||
// else {
|
||||
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
|
||||
// (int)(rawEnd-rawStart), channelMap, "", dataBlock.getDataName(), rawData, getSampleRate());
|
||||
// }
|
||||
// clipDataUnit.setFrequency(dataUnit.getFrequency());
|
||||
// lastClipDataUnit = clipDataUnit;
|
||||
// if (bearingLocaliser != null) {
|
||||
// localiseClip(clipDataUnit, bearingLocaliser, hydrophoneMap);
|
||||
// }
|
||||
// clipDataBlock.addPamData(clipDataUnit);
|
||||
// }
|
||||
//
|
||||
// return 0; // no error.
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
@ -25,7 +25,7 @@ public class WavExportOptions implements Serializable, Cloneable {
|
||||
public static final int SAVEWAV_INDIVIDUAL = 2;
|
||||
|
||||
/**
|
||||
* Flag to indicuate how to save files
|
||||
* Flag to indicate how to save files
|
||||
*/
|
||||
public int wavSaveChoice = SAVEWAV_CONCAT;
|
||||
|
||||
|
@ -38,17 +38,17 @@ public class WavOptionsPanel extends PamPanel {
|
||||
|
||||
this.setLayout((new GridBagLayout()));
|
||||
|
||||
addComponent(this, zeroPad = new JRadioButton("Concat"), c);
|
||||
addComponent(this, zeroPad = new JRadioButton("Zero Pad"), c);
|
||||
|
||||
c.gridx++;
|
||||
|
||||
addComponent(this, noZeroPad = new JRadioButton("Zero pad"), c);
|
||||
addComponent(this, noZeroPad = new JRadioButton("Concatonate"), c);
|
||||
|
||||
c.gridx++;
|
||||
addComponent(this, indvidualWav = new JRadioButton("Individual"), c);
|
||||
|
||||
c.gridx++;
|
||||
addComponent(this, new JLabel(" wav"), c);
|
||||
// c.gridx++;
|
||||
// addComponent(this, new JLabel(" wav"), c);
|
||||
|
||||
// Initialization of object of "ButtonGroup" class.
|
||||
ButtonGroup buttonGroup = new ButtonGroup();
|
||||
@ -97,8 +97,8 @@ public class WavOptionsPanel extends PamPanel {
|
||||
public WavExportOptions getParams(WavExportOptions wavExportOptions) {
|
||||
|
||||
if (zeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
|
||||
if (noZeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
|
||||
if (indvidualWav.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
|
||||
if (noZeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_CONCAT;
|
||||
if (indvidualWav.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_INDIVIDUAL;
|
||||
|
||||
return wavExportOptions;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ public class OLProcessDialog extends PamDialog {
|
||||
private JButton[] settingsButton;
|
||||
private JLabel status, currFile;
|
||||
private JProgressBar globalProgress; // file by file progress 1: nFiles
|
||||
|
||||
private JProgressBar loadedProgress; // progress throgh loaded data
|
||||
private JCheckBox deleteOldData;
|
||||
private JLabel dataInfo;
|
||||
@ -723,7 +724,7 @@ public class OLProcessDialog extends PamDialog {
|
||||
* @author Doug Gillespie
|
||||
*
|
||||
*/
|
||||
class OLMonitor implements TaskMonitor {
|
||||
public class OLMonitor implements TaskMonitor {
|
||||
|
||||
@Override
|
||||
public void setTaskStatus(TaskMonitorData taskMonitorData) {
|
||||
@ -734,6 +735,7 @@ public class OLProcessDialog extends PamDialog {
|
||||
else {
|
||||
currFile.setText(taskMonitorData.fileOrStatus);
|
||||
}
|
||||
|
||||
switch (taskMonitorData.taskActivity) {
|
||||
case LINKING:
|
||||
case LOADING:
|
||||
@ -755,6 +757,7 @@ public class OLProcessDialog extends PamDialog {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (taskMonitorData.taskStatus) {
|
||||
case COMPLETE:
|
||||
globalProgress.setValue(100);
|
||||
@ -878,6 +881,11 @@ public class OLProcessDialog extends PamDialog {
|
||||
public void setNeedaNote(boolean isNeedaNote) {
|
||||
this.isNeedaNote = isNeedaNote;
|
||||
}
|
||||
|
||||
public JProgressBar getGlobalProgress() {
|
||||
return globalProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -43,29 +43,29 @@ import org.controlsfx.control.ToggleSwitch;
|
||||
*
|
||||
*/
|
||||
public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
|
||||
|
||||
/**
|
||||
* This is essentially one PAMGuard stage. PAMGuard may have multiple stages in which case it will have multiple PAMGuiFX instances.
|
||||
*/
|
||||
private PamTabPane mainTabPane;
|
||||
|
||||
|
||||
/**
|
||||
* The preferred width of the side pane.
|
||||
*/
|
||||
public static final double SIDE_PANE_PREF_WIDTH = 250;
|
||||
|
||||
// /**
|
||||
// * Icon for menu
|
||||
// */
|
||||
// public Image menuIconGrey=new Image(getClass().getResourceAsStream("/Resources/MenuButton.png"));
|
||||
//
|
||||
// public Image showButtonGrey=new Image(getClass().getResourceAsStream("/Resources/SidePanelShow2Grey.png"));
|
||||
//
|
||||
// public Image hideButtonGrey=new Image(getClass().getResourceAsStream("/Resources/SidePanelHide2Grey.png"));
|
||||
//
|
||||
// public Image recordStart=new Image(getClass().getResourceAsStream("/Resources/recordStart.png"));
|
||||
//
|
||||
// public Image playPause=new Image(getClass().getResourceAsStream("/Resources/playStart.png"));
|
||||
|
||||
// /**
|
||||
// * Icon for menu
|
||||
// */
|
||||
// public Image menuIconGrey=new Image(getClass().getResourceAsStream("/Resources/MenuButton.png"));
|
||||
//
|
||||
// public Image showButtonGrey=new Image(getClass().getResourceAsStream("/Resources/SidePanelShow2Grey.png"));
|
||||
//
|
||||
// public Image hideButtonGrey=new Image(getClass().getResourceAsStream("/Resources/SidePanelHide2Grey.png"));
|
||||
//
|
||||
// public Image recordStart=new Image(getClass().getResourceAsStream("/Resources/recordStart.png"));
|
||||
//
|
||||
// public Image playPause=new Image(getClass().getResourceAsStream("/Resources/playStart.png"));
|
||||
|
||||
/**
|
||||
* A reference to the stage this PAMGUIFX belongs to.
|
||||
@ -81,18 +81,18 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
* Hiding side pane.
|
||||
*/
|
||||
private HidingPane hidingSidePane;
|
||||
|
||||
|
||||
/**
|
||||
* The Pane which holds everything that sits in hide pane.
|
||||
*/
|
||||
private PamVBox sidePaneContent;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pane which holds main PAMGUARD settings
|
||||
*/
|
||||
private PamVBox settingsPane;
|
||||
|
||||
|
||||
/**
|
||||
* Hiding pane which holds settings
|
||||
*/
|
||||
@ -121,34 +121,34 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
* @param pamGuiManagerFX - the GUI manager.
|
||||
*/
|
||||
public PamGuiFX (PamTabPane mainTabPane, Stage stage, PamGuiManagerFX pamGuiManagerFX){
|
||||
|
||||
|
||||
this.stage=stage;
|
||||
this.pamGuiManagerFX=pamGuiManagerFX;
|
||||
this.mainTabPane = mainTabPane;
|
||||
|
||||
Node layout=createMainPane(mainTabPane, stage);
|
||||
this.mainTabPane = mainTabPane;
|
||||
|
||||
Node layout=createMainPane(mainTabPane, stage);
|
||||
|
||||
//add main pane to PamGui
|
||||
this.getChildren().add(layout);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public PamGuiFX (Stage stage, PamGuiManagerFX pamGuiManagerFX){
|
||||
|
||||
|
||||
this.stage=stage;
|
||||
this.pamGuiManagerFX=pamGuiManagerFX;
|
||||
|
||||
|
||||
//create the main tab pane.
|
||||
this.mainTabPane = new PamTabPane();
|
||||
|
||||
Node layout=createMainPane(mainTabPane, stage);
|
||||
|
||||
//add main pane to PamGui
|
||||
this.getChildren().add(layout);
|
||||
this.mainTabPane = new PamTabPane();
|
||||
|
||||
Node layout=createMainPane(mainTabPane, stage);
|
||||
|
||||
//add main pane to PamGui
|
||||
this.getChildren().add(layout);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the pane which sits inside stage and holds tabs, side pane.
|
||||
* @param mainTabPane - the main tab pane for the scene.
|
||||
@ -174,7 +174,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
//create the button which shows the hiding panel. Although we get this button from the hiding pane, where to place
|
||||
//it and what colour it is etc has to be set for whatever pane it is to be located in.
|
||||
PamButton showButtonRight=hidingSidePane.getShowButton();
|
||||
// showButtonRight.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_LEFT, PamGuiManagerFX.iconColor, PamGuiManagerFX.iconSize));
|
||||
// showButtonRight.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_LEFT, PamGuiManagerFX.iconColor, PamGuiManagerFX.iconSize));
|
||||
showButtonRight.setGraphic(PamGlyphDude.createPamIcon("mdi2c-chevron-left", PamGuiManagerFX.iconColor, PamGuiManagerFX.iconSize));
|
||||
//showLeftButton.setText(PamFontAwesome.ICON_CHEVRON_LEFT);
|
||||
showButtonRight.getStyleClass().add("close-button-left-trans");
|
||||
@ -183,10 +183,10 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
//alter animations to remove/add showButton to tab pane.
|
||||
//TODO- tried to have animation here to hide buttons but didn't appear to work.
|
||||
//Maybe an issue with running another animation from animation thread?
|
||||
// showButton.prefWidthProperty().addListener((listener)->{
|
||||
// mainTabPane.layout(); //Don't need this
|
||||
// });
|
||||
|
||||
// showButton.prefWidthProperty().addListener((listener)->{
|
||||
// mainTabPane.layout(); //Don't need this
|
||||
// });
|
||||
|
||||
hidingSidePane.getTimeLineShow().setOnFinished((value)->{
|
||||
showButtonRight.setPrefWidth(1);
|
||||
showButtonRight.setVisible(false);
|
||||
@ -203,55 +203,55 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
|
||||
PamButton closeButtonLeft=hidingSidePane.getHideButton();
|
||||
closeButtonLeft.getStyleClass().add("close-button-right-trans");
|
||||
// closeButtonLeft.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_RIGHT, Color.DARKGRAY.darker(), PamGuiManagerFX.iconSize));
|
||||
// closeButtonLeft.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_RIGHT, Color.DARKGRAY.darker(), PamGuiManagerFX.iconSize));
|
||||
closeButtonLeft.prefHeightProperty().bind(mainTabPane.getHeaderHeightProperty());
|
||||
|
||||
|
||||
//add hiding pane to main pane.
|
||||
layout.setRight(hidingSidePane);
|
||||
|
||||
|
||||
/**create settings pane. This allows access to primary PAMGUARD settings.**/
|
||||
settingsPane=new PamSettingsMenuPane();
|
||||
settingsPane.setPrefWidth(250);
|
||||
hidingPaneLeft=new HidingPane(Side.LEFT, settingsPane, this, false);
|
||||
hidingPaneLeft.showHidePane(false);
|
||||
|
||||
|
||||
hidingPaneLeft.getStylesheets().addAll(pamGuiManagerFX.getPamSettingsCSS());
|
||||
|
||||
PamButton showButtonLeft=hidingPaneLeft.getShowButton();
|
||||
// showButtonLeft.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.BARS, Color.LIGHTGRAY, PamGuiManagerFX.iconSize));
|
||||
// showButtonLeft.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.BARS, Color.LIGHTGRAY, PamGuiManagerFX.iconSize));
|
||||
showButtonLeft.setGraphic(PamGlyphDude.createPamIcon("mdi2m-menu", Color.LIGHTGRAY, PamGuiManagerFX.iconSize));
|
||||
showButtonLeft.getStyleClass().add("close-button-right-trans");
|
||||
showButtonLeft.setStyle(" -fx-background-radius: 0 0 0 0;");
|
||||
|
||||
|
||||
PamButton closeRightButton=hidingPaneLeft.getHideButton();
|
||||
closeRightButton.setPrefWidth(40);
|
||||
closeRightButton.getStyleClass().add("close-button-left-trans");
|
||||
// closeRightButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_LEFT, Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
// closeRightButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CHEVRON_LEFT, Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
closeRightButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-chevron-left", Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
closeRightButton.prefHeightProperty().bind(mainTabPane.getHeaderHeightProperty());
|
||||
|
||||
|
||||
//add hiding pane to main pane.
|
||||
layout.setLeft(hidingPaneLeft);
|
||||
|
||||
// //Create a button which sits at end of tab pane
|
||||
// settingsButton = new PamButton();
|
||||
// settingsButton.setMinWidth(Control.USE_PREF_SIZE);
|
||||
// settingsButton.setGraphic(Glyph.create("FontAwesome|BARS").size(22).color(Color.DARKGREY.darker()));
|
||||
// settingsButton.getStyleClass().add("transparent-button");
|
||||
//// settingsButton.setPadding(new Insets(0,10,0,10));
|
||||
// settingsButton.setOnAction(e -> {
|
||||
// //TODO-open settings menu
|
||||
// });
|
||||
|
||||
// //Create a button which sits at end of tab pane
|
||||
// settingsButton = new PamButton();
|
||||
// settingsButton.setMinWidth(Control.USE_PREF_SIZE);
|
||||
// settingsButton.setGraphic(Glyph.create("FontAwesome|BARS").size(22).color(Color.DARKGREY.darker()));
|
||||
// settingsButton.getStyleClass().add("transparent-button");
|
||||
//// settingsButton.setPadding(new Insets(0,10,0,10));
|
||||
// settingsButton.setOnAction(e -> {
|
||||
// //TODO-open settings menu
|
||||
// });
|
||||
|
||||
mainTabPane.setTabEndRegion(showButtonRight);
|
||||
mainTabPane.setTabStartRegion(showButtonLeft);
|
||||
// mainTabPane.getStyleClass().add(Styles.TABS_FLOATING);
|
||||
// mainTabPane.getStyleClass().add(Styles.TABS_FLOATING);
|
||||
|
||||
mainTabPane.getAddTabButton().setOnAction((value)->{
|
||||
addPamTab(new TabInfo("Display " + (this.getNumTabs()+1)), null ,true);
|
||||
mainTabPane.layout();
|
||||
addPamTab(new TabInfo("Display " + (this.getNumTabs()+1)), null ,true);
|
||||
mainTabPane.layout();
|
||||
});
|
||||
|
||||
|
||||
//now have a holder - add the loading pane.
|
||||
/**create left hiding pane**/
|
||||
loadPane=new PamLoadingPane(this.pamGuiManagerFX);
|
||||
@ -259,14 +259,14 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
hidingLoadPane.setPrefHeight(110);
|
||||
hidingLoadPane.removeHideButton();
|
||||
hidingLoadPane.showHidePane(false);
|
||||
|
||||
|
||||
PamBorderPane layoutHolder=new PamBorderPane(layout);
|
||||
layoutHolder.setTop(hidingLoadPane);
|
||||
|
||||
return layoutHolder;
|
||||
|
||||
return layoutHolder;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the load pane for the PamGuiFX- shows loading data and other status updates.
|
||||
* @return the PamLoadingf Pane
|
||||
@ -281,79 +281,79 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public void show(){
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convenience function to add a closable tab to the display with a new UserDisplayNodeFX.
|
||||
* @param name- tab name.
|
||||
* @param content- content to add to the tab. Can be null;
|
||||
*/
|
||||
public PamGuiTabFX addPamTab(TabInfo tabInfo, UserDisplayNodeFX content, boolean detachable ){
|
||||
//create holder pane and add to tab
|
||||
//create holder pane and add to tab
|
||||
PamGuiTabFX newTab = new PamGuiTabFX(tabInfo, this);
|
||||
|
||||
|
||||
newTab.setToolbar(new ToolBarPane(newTab));
|
||||
|
||||
|
||||
//static displays have non closable tabs and non resizable displays
|
||||
if (content!=null){
|
||||
newTab.setClosable(!content.isStaticDisplay());
|
||||
newTab.setResizableDisplays(!content.isStaticDisplay());
|
||||
if (content!=null){
|
||||
newTab.setClosable(!content.isStaticDisplay());
|
||||
newTab.setResizableDisplays(!content.isStaticDisplay());
|
||||
|
||||
if (content.isStaticDisplay()){
|
||||
//if static, then add to center.
|
||||
newTab.getContentHolder().setCenter(content.getNode());
|
||||
}
|
||||
else{
|
||||
//add content- will not add and return null if content is null
|
||||
newTab.addInternalPane(content);
|
||||
}
|
||||
}
|
||||
|
||||
newTab.setOnClosed((action)->{
|
||||
//when a tab is closer.
|
||||
for (int i=0; i<newTab.getInternalPanes().size(); i++) {
|
||||
System.out.println("REMOVE TAB: " + newTab.getInternalPanes().size());
|
||||
if (content.isStaticDisplay()){
|
||||
//if static, then add to center.
|
||||
newTab.getContentHolder().setCenter(content.getNode());
|
||||
}
|
||||
else{
|
||||
//add content- will not add and return null if content is null
|
||||
newTab.addInternalPane(content);
|
||||
}
|
||||
}
|
||||
|
||||
newTab.getInternalPanes().get(i).getUserDisplayNode().closeNode();
|
||||
if (newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl()!=null) {
|
||||
System.out.println("REMOVE CONTROLLED DISPLAY UNIT: " + newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl());
|
||||
//the display is a standalone display and so remove the tab means the controlled unit should be removed from the data model
|
||||
PamController.getInstance().removeControlledUnt(newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl());
|
||||
PamGuiManagerFX.getInstance().getDataModelFX().dataModeltoPamModel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
newTab.setDetachable(detachable);
|
||||
|
||||
//add tab
|
||||
mainTabPane.getTabs().add(newTab);
|
||||
|
||||
return newTab;
|
||||
newTab.setOnClosed((action)->{
|
||||
//when a tab is closer.
|
||||
for (int i=0; i<newTab.getInternalPanes().size(); i++) {
|
||||
System.out.println("REMOVE TAB: " + newTab.getInternalPanes().size());
|
||||
|
||||
newTab.getInternalPanes().get(i).getUserDisplayNode().closeNode();
|
||||
if (newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl()!=null) {
|
||||
System.out.println("REMOVE CONTROLLED DISPLAY UNIT: " + newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl());
|
||||
//the display is a standalone display and so remove the tab means the controlled unit should be removed from the data model
|
||||
PamController.getInstance().removeControlledUnt(newTab.getInternalPanes().get(i).getUserDisplayNode().getUserDisplayControl());
|
||||
PamGuiManagerFX.getInstance().getDataModelFX().dataModeltoPamModel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
newTab.setDetachable(detachable);
|
||||
|
||||
//add tab
|
||||
mainTabPane.getTabs().add(newTab);
|
||||
|
||||
return newTab;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a tab for the data model.
|
||||
* @param dataModelPaneFX - the data model
|
||||
*/
|
||||
public DataModelPaneFX addDataModelTab() {
|
||||
|
||||
|
||||
PamGuiTabFX newTab = new PamGuiTabFX(new TabInfo("Data Model"), this);
|
||||
newTab.setToolbar(new ToolBarPane(newTab));
|
||||
|
||||
newTab.setClosable(false); //can't close a data model
|
||||
newTab.setDetachable(false);
|
||||
mainTabPane.getTabs().add(newTab);
|
||||
DataModelPaneFX dataModelPaneFX=new DataModelPaneFX();
|
||||
|
||||
//create controls in the tool bar for the data model
|
||||
dataModelPaneFX.createToolbarControls(newTab);
|
||||
|
||||
newTab.setMainContent(dataModelPaneFX);
|
||||
return dataModelPaneFX;
|
||||
|
||||
|
||||
newTab.setClosable(false); //can't close a data model
|
||||
newTab.setDetachable(false);
|
||||
mainTabPane.getTabs().add(newTab);
|
||||
DataModelPaneFX dataModelPaneFX=new DataModelPaneFX();
|
||||
|
||||
//create controls in the tool bar for the data model
|
||||
dataModelPaneFX.createToolbarControls(newTab);
|
||||
|
||||
newTab.setMainContent(dataModelPaneFX);
|
||||
return dataModelPaneFX;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all tabs for this PamGuiFX
|
||||
* @return list of tabs in the PamGuiFX
|
||||
@ -365,7 +365,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a tab to the tab pane.
|
||||
* @param pamGuiTabFX - the tab to add
|
||||
@ -374,7 +374,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
// add a tab.
|
||||
mainTabPane.getTabs().add(pamGuiTabFX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add tabs to the tab pane.
|
||||
* @param pamGuiTabFX - the tabs to add
|
||||
@ -383,7 +383,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
// add a tab.>
|
||||
mainTabPane.getTabs().addAll(pamGuiTabFXs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of tabs currently open.
|
||||
* @return the number of tabs.
|
||||
@ -391,7 +391,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public int getNumTabs(){
|
||||
return mainTabPane.getTabs().size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a tab
|
||||
* @param i - tab index
|
||||
@ -400,16 +400,16 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public PamGuiTabFX getTab(int i){
|
||||
return (PamGuiTabFX) mainTabPane.getTabs().get(i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Select a tab
|
||||
* @param j - index
|
||||
*/
|
||||
public void selectTab(int j) {
|
||||
this.mainTabPane.getSelectionModel().select(j);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the tool bar pane. The top of each tab content node contains a tool
|
||||
@ -423,24 +423,24 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
*
|
||||
*/
|
||||
public class ToolBarPane extends PamBorderPane {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Record/batch process button. In real time starts/stops data acquisition. In viewer mode
|
||||
* opens the batch run manager to allow batch processing of data e.g. reclassifying clicks.
|
||||
*/
|
||||
private PamButton recordButton;
|
||||
|
||||
|
||||
/**
|
||||
*Play/pause button. Plays back sound in real time/viewer mode.
|
||||
*/
|
||||
private PamButton playButton;
|
||||
|
||||
|
||||
/**
|
||||
* Holds all extra controls in the toolbar.
|
||||
*/
|
||||
private PamHBox centerHBox;
|
||||
|
||||
|
||||
/**
|
||||
* Height of the toolbar.
|
||||
*/
|
||||
@ -466,59 +466,76 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
* Button to select what autosort option for windows.
|
||||
*/
|
||||
private MenuButton autoSortChoice;
|
||||
|
||||
|
||||
public ToolBarPane(PamGuiTabFX pamGuiTab){
|
||||
super();
|
||||
|
||||
this.pamGuiTab=pamGuiTab;
|
||||
|
||||
//create record and play buttons.
|
||||
PamHBox playControls=new PamHBox();
|
||||
recordButton=new PamButton();
|
||||
// recordButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CIRCLE, Color.LIMEGREEN, PamGuiManagerFX.iconSize));
|
||||
recordButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-record-circle", Color.RED, PamGuiManagerFX.iconSize));
|
||||
recordButton.getStyleClass().add("transparent-button");
|
||||
|
||||
//recordButton.setStyle(" -fx-background-radius: 50;");
|
||||
|
||||
recordButton.setOnAction((action)->{
|
||||
if (PamController.getInstance().getPamStatus()==PamController.PAM_RUNNING){
|
||||
PamController.getInstance().pamStop();
|
||||
pamGuiManagerFX.setPamRunning(false);
|
||||
}
|
||||
else {
|
||||
PamController.getInstance().pamStart();
|
||||
pamGuiManagerFX.setPamRunning(true);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
playButton=new PamButton();
|
||||
// playButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.PLAY, Color.BLACK, PamGuiManagerFX.iconSize));
|
||||
playButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play", Color.BLACK, PamGuiManagerFX.iconSize));
|
||||
playButton.getStyleClass().add("transparent-button");
|
||||
//playButton.setStyle(" -fx-background-radius: 50;");
|
||||
playButton.setOnAction((action)->{
|
||||
//TODO
|
||||
//start pamguard
|
||||
//PamController.getInstance().pamStart();
|
||||
});
|
||||
|
||||
|
||||
playControls.getChildren().addAll(recordButton,playButton);
|
||||
playControls.setSpacing(10);
|
||||
playControls.setPadding(new Insets(0,10,0,20));
|
||||
// playControls.getStyleClass().add("pane-opaque");
|
||||
playControls.setPrefHeight(prefHeight);
|
||||
playControls.setAlignment(Pos.CENTER);
|
||||
|
||||
this.pamGuiTab=pamGuiTab;
|
||||
|
||||
PamHBox analysisControls=new PamHBox();
|
||||
analysisControls.setSpacing(10);
|
||||
analysisControls.setPadding(new Insets(0,10,0,20));
|
||||
// playControls.getStyleClass().add("pane-opaque");
|
||||
analysisControls.setPrefHeight(prefHeight);
|
||||
analysisControls.setAlignment(Pos.CENTER);
|
||||
|
||||
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
|
||||
|
||||
//in PMAGUard viewer mode we want a reporcess button
|
||||
|
||||
PamButton reProcessButton=new PamButton("Reprocess...");
|
||||
reProcessButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog-transfer", PamGuiManagerFX.iconSize));
|
||||
reProcessButton.setOnAction((action->{
|
||||
|
||||
}));
|
||||
|
||||
|
||||
analysisControls.getChildren().addAll(reProcessButton);
|
||||
|
||||
}
|
||||
else {
|
||||
//real time mode
|
||||
//create record and play buttons.
|
||||
recordButton=new PamButton();
|
||||
// recordButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CIRCLE, Color.LIMEGREEN, PamGuiManagerFX.iconSize));
|
||||
recordButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-record-circle", Color.RED, PamGuiManagerFX.iconSize));
|
||||
recordButton.getStyleClass().add("transparent-button");
|
||||
recordButton.setStyle("-fx-padding: 0 10 0 10;");
|
||||
//recordButton.setStyle(" -fx-background-radius: 50;");
|
||||
|
||||
recordButton.setOnAction((action)->{
|
||||
if (PamController.getInstance().getPamStatus()==PamController.PAM_RUNNING){
|
||||
PamController.getInstance().pamStop();
|
||||
pamGuiManagerFX.setPamRunning(false);
|
||||
}
|
||||
else {
|
||||
PamController.getInstance().pamStart();
|
||||
pamGuiManagerFX.setPamRunning(true);
|
||||
}
|
||||
});
|
||||
|
||||
// playButton=new PamButton();
|
||||
//// playButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.PLAY, Color.BLACK, PamGuiManagerFX.iconSize));
|
||||
// playButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play", Color.BLACK, PamGuiManagerFX.iconSize));
|
||||
// playButton.getStyleClass().add("transparent-button");
|
||||
// //playButton.setStyle(" -fx-background-radius: 50;");
|
||||
// playButton.setOnAction((action)->{
|
||||
// //TODO
|
||||
// //start pamguard
|
||||
// //PamController.getInstance().pamStart();
|
||||
// });
|
||||
|
||||
analysisControls.getChildren().addAll(recordButton);
|
||||
|
||||
}
|
||||
|
||||
//create window editing button. This holds a toggle to edit windows and options.
|
||||
rightHBox=new PamHBox();
|
||||
rightHBox.setAlignment(Pos.CENTER_LEFT);
|
||||
rightHBox.setPadding(new Insets(0,10,0,20));
|
||||
rightHBox.setSpacing(5);
|
||||
// rightHBox.getStyleClass().add("pane-opaque");
|
||||
|
||||
// rightHBox.getStyleClass().add("pane-opaque");
|
||||
|
||||
editWindows=new ToggleSwitch("Resize");
|
||||
//HACK,
|
||||
editWindows.setPadding(new Insets(8,0,0,0));
|
||||
@ -527,56 +544,56 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
boolean editable=!pamGuiTab.getEditable();
|
||||
pamGuiTab.setPanesEditable(editable);
|
||||
});
|
||||
|
||||
|
||||
//add a choice box to allow users to automatically resize windows.
|
||||
autoSortChoice=new MenuButton();
|
||||
autoSortChoice.getStyleClass().add("transparent-button");
|
||||
// autoSortChoice.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.ELLIPSIS_V,
|
||||
// autoSortChoice.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.ELLIPSIS_V,
|
||||
autoSortChoice.setGraphic(PamGlyphDude.createPamIcon("mdi2d-dots-vertical",
|
||||
Color.DARKGRAY, PamGuiManagerFX.iconSize));
|
||||
|
||||
|
||||
MenuItem tile=new MenuItem("Tile");
|
||||
tile.setOnAction((action)->{
|
||||
pamGuiTab.autoSortPanes(PamGuiTabFX.SORT_TILE);
|
||||
});
|
||||
|
||||
|
||||
MenuItem vertical=new MenuItem("Horizontal");
|
||||
vertical.setOnAction((action)->{
|
||||
pamGuiTab.autoSortPanes(PamGuiTabFX.SORT_HORIZONTAL);
|
||||
});
|
||||
|
||||
|
||||
MenuItem horizontal=new MenuItem("Vertical");
|
||||
horizontal.setOnAction((action)->{
|
||||
pamGuiTab.autoSortPanes(PamGuiTabFX.SORT_VERTICAL);
|
||||
});
|
||||
|
||||
|
||||
autoSortChoice.getItems().addAll(tile, vertical, horizontal);
|
||||
|
||||
|
||||
rightHBox.getChildren().addAll(editWindows, autoSortChoice);
|
||||
|
||||
|
||||
|
||||
//create content hboc for extra controls.
|
||||
centerHBox=new PamHBox();
|
||||
centerHBox.setSpacing(10);
|
||||
//need to set this style to prevent the pane form being transparent.
|
||||
//centerHBox.getStyleClass().add("pane-opaque");
|
||||
centerHBox.setPrefHeight(prefHeight);
|
||||
|
||||
|
||||
this.setCenter(centerHBox);
|
||||
this.setLeft(playControls);
|
||||
this.setLeft(analysisControls);
|
||||
this.setRight(rightHBox);
|
||||
|
||||
|
||||
this.setPrefHeight(prefHeight);
|
||||
this.getStyleClass().add("pane-opaque");
|
||||
|
||||
|
||||
//this.setPadding(new Insets(0,0,0,0));
|
||||
|
||||
|
||||
this.toFront();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the content HBox. This holds any extra controls in the top tool bar.
|
||||
* @return HBox to add extra toolbar content to.
|
||||
@ -584,7 +601,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public PamHBox getCenterHBox(){
|
||||
return centerHBox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a node to the content area of the toolbar.
|
||||
* @param node - node to add.
|
||||
@ -592,7 +609,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public void addToolbarNode(Node node){
|
||||
centerHBox.getChildren().add(node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the button which starts and stops PAMGUARD.
|
||||
* @return the button.
|
||||
@ -600,7 +617,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public Button getRecordButton(){
|
||||
return recordButton;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the HBox on the right hand side of the toolbar.
|
||||
* @return hbox on right hand side of display.
|
||||
@ -616,7 +633,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
|
||||
|
||||
/**
|
||||
* Show the controls which allows manula resizing of the pane.
|
||||
* Show the controls which allows manual resizing of the pane.
|
||||
* @param resize.
|
||||
*/
|
||||
public void showResizableControl(boolean resize) {
|
||||
@ -627,7 +644,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all record buttons from the different toolbars in this stage.
|
||||
* @return list of record buttons.
|
||||
@ -640,7 +657,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
}
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove an internal pane if it is contained within any tabs within the PamGuiFX
|
||||
* @param removeNode - remove the pane if it contains this node.
|
||||
@ -651,7 +668,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
tabs.get(i).removeInternalPane(removeNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the PamLoadPnae- this shows the pane that contains progress bars for loading data.
|
||||
* @param show - true to show pane.
|
||||
@ -676,13 +693,13 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
* @param pamTaskUpdate - information on a thread which s currently doing some work.
|
||||
*/
|
||||
public void notifyLoadProgress(PamTaskUpdate pamTaskUpdate) {
|
||||
Platform.runLater (() -> this.loadPane.updateLoadPane(pamTaskUpdate));
|
||||
Platform.runLater (() -> this.loadPane.updateLoadPane(pamTaskUpdate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pamStarted() {
|
||||
this.pamGuiManagerFX.pamStarted();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -693,19 +710,19 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
@Override
|
||||
public void modelChanged(int changeType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addControlledUnit(PamControlledUnit unit) {
|
||||
this.pamGuiManagerFX.addControlledUnit(unit);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeControlledUnit(PamControlledUnit unit) {
|
||||
this.pamGuiManagerFX.removeControlledUnit(unit);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -716,7 +733,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -733,7 +750,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
@Override
|
||||
public void enableGUIControl(boolean enable) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -769,7 +786,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public PamVBox getSidePane() {
|
||||
return sidePaneContent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the side pane. The side pane holds extra quick access
|
||||
* controls for modules.
|
||||
@ -778,7 +795,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
|
||||
public void showSidePane(boolean show) {
|
||||
this.hidingSidePane.showHidePane(show);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rename a tab at a selected index.
|
||||
* @param selectedItem - the new name
|
||||
|
@ -1,15 +1,9 @@
|
||||
package pamViewFX;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import atlantafx.base.controls.ToggleSwitch;
|
||||
import atlantafx.base.theme.PrimerDark;
|
||||
import atlantafx.base.theme.PrimerLight;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
@ -96,7 +90,16 @@ public class PamLauncherPane extends PamBorderPane {
|
||||
// this.getStylesheets().add(getClass().getResource(primerPAMGuard).toExternalForm());
|
||||
// this.getStylesheets().add(getClass().getResource(new PrimerDark().getUserAgentStylesheet()).toExternalForm());
|
||||
PamStylesManagerFX.getPamStylesManagerFX().setCurStyle(new PamDefaultStyle());
|
||||
|
||||
}
|
||||
|
||||
private void setStyle(boolean PAMGuardFX) {
|
||||
this.getStylesheets().clear();
|
||||
|
||||
if (PAMGuardFX) {
|
||||
PamStylesManagerFX.getPamStylesManagerFX().setCurStyle(new PamAtlantaStyle());
|
||||
this.getStylesheets().addAll(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
|
||||
this.setStyle("-fx-background-color: -fx-darkbackground");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* Pane which holds settings menu. All primary settings are accessed from this pane which sits in a hiding pane to the right
|
||||
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||
|
||||
import PamView.ColourScheme;
|
||||
import PamView.PamColors;
|
||||
import atlantafx.base.theme.CupertinoDark;
|
||||
import atlantafx.base.theme.CupertinoLight;
|
||||
import atlantafx.base.theme.PrimerDark;
|
||||
import atlantafx.base.theme.PrimerLight;
|
||||
|
||||
@ -53,6 +55,7 @@ public class PamAtlantaStyle extends PamDefaultStyle {
|
||||
// private String guiCSS = new NordDark().getUserAgentStylesheet();
|
||||
// protected String primerlight = "/Resources/css/primer-light.css";
|
||||
protected String primerlight = new PrimerLight().getUserAgentStylesheet();
|
||||
// protected String primerlight = new CupertinoLight().getUserAgentStylesheet();
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard standard
|
||||
@ -62,6 +65,7 @@ public class PamAtlantaStyle extends PamDefaultStyle {
|
||||
// private String dialogCSS = new PrimerDark().getUserAgentStylesheet();
|
||||
// protected String primerdark = "/Resources/css/primer-dark.css";
|
||||
protected String primerdark = new PrimerDark().getUserAgentStylesheet();
|
||||
// protected String primerdark = new CupertinoDark().getUserAgentStylesheet();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
|
||||
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
|
||||
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
|
||||
import org.jamdev.jpamutils.wavFiles.AudioData;
|
||||
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -31,7 +32,7 @@ public class ClickDLTest {
|
||||
System.out.println("*****Click classification Deep Learning C*****");
|
||||
|
||||
//relative paths to the resource folders.
|
||||
String relModelPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/updated_model/saved_model.pb";
|
||||
String relModelPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/uniform_model/saved_model.pb";
|
||||
String clicksPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/clicks.mat";
|
||||
|
||||
Path path = Paths.get(relModelPath);
|
||||
@ -45,14 +46,17 @@ public class ClickDLTest {
|
||||
//create the transforms.
|
||||
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
|
||||
|
||||
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV));
|
||||
|
||||
//waveform transforms.
|
||||
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE_SCIPY, 248000.));
|
||||
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PEAK_TRIM, 128, 1));
|
||||
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV, 0., 1, AudioData.ZSCORE));
|
||||
|
||||
genericModelParams.dlTransfromParams = dlTransformParamsArr;
|
||||
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
|
||||
|
||||
//create the clicks.
|
||||
path = Paths.get(clicksPath);
|
||||
ArrayList<GroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
|
||||
ArrayList<PredGroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
|
||||
|
||||
//prep the model
|
||||
genericModelWorker.prepModel(genericModelParams, null);
|
||||
@ -61,20 +65,22 @@ public class ClickDLTest {
|
||||
|
||||
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
|
||||
|
||||
int i=0;
|
||||
for (int i=0; i<1; i++) {
|
||||
|
||||
float prediction = 0;
|
||||
|
||||
groupedData.add(clicks.get(i)); //TODO for loop
|
||||
|
||||
System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
|
||||
float prediction = (float) clicks.get(i).getPrediction()[0];
|
||||
|
||||
groupedData.add(clicks.get(i)); //TODO for loop
|
||||
|
||||
//System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
|
||||
|
||||
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,SAMPLE_RATE, 0);
|
||||
|
||||
float[] output = genericPrediction.get(i).getPrediction();
|
||||
|
||||
System.out.println(String.format("Click %d Predicted output: %.2f true output: %.2f passed: %b", clicks.get(i).getUID(),
|
||||
output[0], prediction, output[0]>prediction*0.9 && output[0]<prediction*1.1));
|
||||
|
||||
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,SAMPLE_RATE, 0);
|
||||
|
||||
float[] output = genericPrediction.get(0).getPrediction();
|
||||
|
||||
System.out.println(String.format("Click %d Predicted output: %.2f true output: %.2f passed: %b", clicks.get(i).getUID(),
|
||||
output[0], prediction, output[0]>prediction*0.9 && output[0]<prediction*1.1));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -82,7 +88,7 @@ public class ClickDLTest {
|
||||
/**
|
||||
* Import a bunch of clicks from a .mat file
|
||||
*/
|
||||
public static ArrayList<GroupedRawData> importClicks(String filePath, float sR) {
|
||||
public static ArrayList<PredGroupedRawData> importClicks(String filePath, float sR) {
|
||||
|
||||
try {
|
||||
Mat5File mfr = Mat5.readFromFile(filePath);
|
||||
@ -91,9 +97,9 @@ public class ClickDLTest {
|
||||
Struct mlArrayRetrived = mfr.getStruct( "clickpreds" );
|
||||
|
||||
int numClicks= mlArrayRetrived.getNumCols();
|
||||
ArrayList<GroupedRawData> clicks = new ArrayList<GroupedRawData>(numClicks);
|
||||
ArrayList<PredGroupedRawData> clicks = new ArrayList<PredGroupedRawData>(numClicks);
|
||||
|
||||
GroupedRawData clickData;
|
||||
PredGroupedRawData clickData;
|
||||
for (int i=0; i<numClicks; i++) {
|
||||
Matrix clickWav= mlArrayRetrived.get("wave", i);
|
||||
|
||||
@ -107,10 +113,12 @@ public class ClickDLTest {
|
||||
Matrix channelMap= mlArrayRetrived.get("channelMap", i);
|
||||
Matrix startSample= mlArrayRetrived.get("startSample", i);
|
||||
Matrix sampleDuration= mlArrayRetrived.get("sampleDuration", i);
|
||||
Matrix pred= mlArrayRetrived.get("pred", i);
|
||||
|
||||
clickData = new GroupedRawData(clickmillis.getLong(0), channelMap.getInt(0), startSample.getLong(0), sampleDuration.getLong(0), sampleDuration.getInt(0));
|
||||
clickData = new PredGroupedRawData(clickmillis.getLong(0), channelMap.getInt(0), startSample.getLong(0), sampleDuration.getLong(0), sampleDuration.getInt(0));
|
||||
clickData.setUID(clickUID.getLong(0));
|
||||
clickData.setRawData(clickwaveform);
|
||||
clickData.setPrediction(new double[] {pred.getDouble(0), pred.getDouble(1)});
|
||||
|
||||
clicks.add(clickData);
|
||||
}
|
||||
@ -124,5 +132,25 @@ public class ClickDLTest {
|
||||
}
|
||||
}
|
||||
|
||||
public static class PredGroupedRawData extends GroupedRawData {
|
||||
|
||||
private double[] prediction;
|
||||
|
||||
public double[] getPrediction() {
|
||||
return prediction;
|
||||
}
|
||||
|
||||
public void setPrediction(double[] prediction) {
|
||||
this.prediction = prediction;
|
||||
}
|
||||
|
||||
public PredGroupedRawData(long timeMilliseconds, int channelBitmap, long startSample, long duration, int samplesize) {
|
||||
super(timeMilliseconds, channelBitmap, startSample, duration, samplesize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -218,8 +218,7 @@ public class DelphinIDTest {
|
||||
//the values for the whistle detector.
|
||||
double[][] pamguardWhistleImage = whistleScatter2Image(whistleValues);
|
||||
|
||||
|
||||
System.out.println("Size python: " + compressedWhistleImage.length + " x " + compressedWhistleImage[0].length);
|
||||
//System.out.println("Size python: " + compressedWhistleImage.length + " x " + compressedWhistleImage[0].length);
|
||||
|
||||
float[][][] input = new float[1][][];
|
||||
input[0] = JamArr.doubleToFloat(compressedWhistleImage);
|
||||
@ -255,7 +254,6 @@ public class DelphinIDTest {
|
||||
|
||||
System.out.println("DelphinID mode test end");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,23 +1,10 @@
|
||||
package wavFiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
//import org.kc7bfi.jflac.util.ByteData;
|
||||
import org.jflac.util.ByteData;
|
||||
|
||||
import clickDetector.WindowsFile;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
|
||||
public class WavFile {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user