mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-24 16:12:24 +00:00
Bug fixes to Match Template classifier
1) When a large template was imported only 1: fftLength of the mathc waveform was used and so clicks would be correlated with noise. The peak of the template is now used when the peak search function is selected. 2) The plus button in the tab pane had disappeared. 3) Seems like the decimators were the wrong round. So the waveforms were using an up sample function when they should have been using a decimator function. and vice versa...major bug when using different sample rates!
This commit is contained in:
parent
be88f4b296
commit
1b9d80b0eb
@ -8,7 +8,6 @@
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
|
88
src/Array/layoutFX/InterpChoicePane.java
Normal file
88
src/Array/layoutFX/InterpChoicePane.java
Normal file
@ -0,0 +1,88 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Choice box which allows selection of interpolation options.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class InterpChoicePane extends InterpSettingsPane {
|
||||
|
||||
/**
|
||||
* Interp choice box.
|
||||
*/
|
||||
private ChoiceBox<Integer> interpChoiceBox;
|
||||
|
||||
public InterpChoicePane() {
|
||||
|
||||
interpChoiceBox = new ChoiceBox<Integer>();
|
||||
interpChoiceBox.getItems().addAll(interpChoice);
|
||||
interpChoiceBox.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
interpChoiceBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Integer item) {
|
||||
if (item ==null) return "null";
|
||||
return getInterpString(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer fromString(String unused) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
|
||||
this.setCenter(interpChoiceBox);
|
||||
|
||||
}
|
||||
|
||||
public void setSelection(int option) {
|
||||
|
||||
interpChoiceBox.getSelectionModel().select(Integer.valueOf(option));
|
||||
|
||||
// useLatest.setSelected(option == PamArray.ORIGIN_USE_LATEST);
|
||||
// useInterpolate.setSelected(option == PamArray.ORIGIN_INTERPOLATE);
|
||||
// usePrevious.setSelected(option == PamArray.ORIGIN_USE_PRECEEDING);
|
||||
}
|
||||
|
||||
public int getSelection() {
|
||||
int sel = getSelectedInterpType();
|
||||
if (((1<<sel) & allowedValues) == 0) {
|
||||
PamDialogFX.showWarning("The selected interpolation is not available with the selected reference position");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enableControls() {
|
||||
interpChoiceBox.getItems().clear();
|
||||
|
||||
for (int i=0; i<interpChoice.length ; i++) {
|
||||
|
||||
if ((allowedValues & (1<<interpChoice[i])) != 0){
|
||||
interpChoiceBox.getItems().add(interpChoice[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSelectedInterpType() {
|
||||
Integer choice = interpChoiceBox.getSelectionModel().getSelectedItem();
|
||||
if (choice == null) {
|
||||
return -1;
|
||||
}
|
||||
else return choice;
|
||||
}
|
||||
|
||||
|
||||
}
|
698
src/Array/layoutFX/StreamerSettingsPane.java
Normal file
698
src/Array/layoutFX/StreamerSettingsPane.java
Normal file
@ -0,0 +1,698 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import org.controlsfx.control.PopOver;
|
||||
|
||||
import Array.HydrophoneLocator;
|
||||
import Array.HydrophoneLocators;
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import Array.sensors.ArrayParameterType;
|
||||
import Array.sensors.ArraySensorFieldType;
|
||||
import Array.streamerOrigin.HydrophoneOriginMethod;
|
||||
import Array.streamerOrigin.HydrophoneOriginMethods;
|
||||
import Array.streamerOrigin.HydrophoneOriginSystem;
|
||||
import Array.streamerOrigin.OriginDialogComponent;
|
||||
import Array.streamerOrigin.OriginSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.SettingsPane;
|
||||
import PamUtils.LatLong;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.validator.PamValidator;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
|
||||
|
||||
/**
|
||||
* A JavaFX settings pane for a streamer.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class StreamerSettingsPane extends SettingsPane<Streamer> {
|
||||
|
||||
private final static double MAX_TEXTFIELD_WIDTH = 80;
|
||||
|
||||
|
||||
public PamBorderPane mainPane;
|
||||
|
||||
|
||||
private ComboBox<HydrophoneOriginSystem> originMethod;
|
||||
|
||||
|
||||
private PamBorderPane originPanel;
|
||||
|
||||
/**
|
||||
* The default streamer
|
||||
*/
|
||||
public Streamer defaultStreamer;
|
||||
|
||||
|
||||
/**
|
||||
* The current array
|
||||
*/
|
||||
private PamArray currentArray;
|
||||
|
||||
/**
|
||||
* The current origin methods
|
||||
*/
|
||||
private HydrophoneOriginMethod currentOriginMethod;
|
||||
|
||||
/*
|
||||
* The current origin method pane.
|
||||
*/
|
||||
private Pane currentOriginComponent;
|
||||
|
||||
/**
|
||||
* Interpolation panel
|
||||
*/
|
||||
private InterpChoicePane interpPane;
|
||||
|
||||
|
||||
private TextField xPos;
|
||||
|
||||
|
||||
private Validator validator = new PamValidator();
|
||||
|
||||
|
||||
private TextField yPos;
|
||||
|
||||
|
||||
private TextField zPos;
|
||||
|
||||
|
||||
private TextField zPosErr;
|
||||
|
||||
|
||||
private TextField xPosErr;
|
||||
|
||||
|
||||
private Label depthLabel;
|
||||
|
||||
|
||||
private TextField yPosErr;
|
||||
|
||||
|
||||
private Label depthLabel2;
|
||||
|
||||
|
||||
private TextField heading;
|
||||
|
||||
|
||||
private TextField roll;
|
||||
|
||||
|
||||
private TextField pitch;
|
||||
|
||||
|
||||
private ComboBox localiserMethod;
|
||||
|
||||
|
||||
private SensorSourcePane[] sensorComponents;
|
||||
|
||||
|
||||
private Label depthSensorLabel;
|
||||
|
||||
|
||||
/**
|
||||
* Button for extra origin params.
|
||||
*/
|
||||
private PamButton originButton;
|
||||
|
||||
|
||||
|
||||
public StreamerSettingsPane() {
|
||||
super(null);
|
||||
|
||||
mainPane = new PamBorderPane();
|
||||
mainPane.setCenter(getStreamerPane());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the streamer pane
|
||||
* @return get the pane.
|
||||
*/
|
||||
private Pane getStreamerPane(){
|
||||
|
||||
String reciever = PamController.getInstance().getGlobalMediumManager().getRecieverString();
|
||||
|
||||
Label label = new Label("Geo-reference Position");
|
||||
PamGuiManagerFX.titleFont2style(label);
|
||||
|
||||
//holds advanced setings for new origin methods.
|
||||
originPanel = new PamBorderPane();
|
||||
PopOver popOver = new PopOver();
|
||||
popOver.setContentNode(originPanel);
|
||||
|
||||
originMethod = new ComboBox<HydrophoneOriginSystem>();
|
||||
originButton = new PamButton();
|
||||
originButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-crosshairs-gps"));
|
||||
originButton.setOnAction((a)->{
|
||||
popOver.show(originButton);
|
||||
});
|
||||
originMethod.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
PamHBox originHolder = new PamHBox();
|
||||
originHolder.setSpacing(5);
|
||||
originHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
originHolder.getChildren().addAll(originMethod,originButton);
|
||||
originHolder.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(originMethod, Priority.ALWAYS);
|
||||
|
||||
int n = HydrophoneOriginMethods.getInstance().getCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
originMethod.getItems().add(HydrophoneOriginMethods.getInstance().getMethod(i));
|
||||
}
|
||||
|
||||
Label hydroMovementLabel = new Label(reciever +" Movement Model");
|
||||
|
||||
//listener for when a new origin method is called.
|
||||
originMethod.setOnAction((action)->{
|
||||
newOriginMethod();
|
||||
});
|
||||
|
||||
interpPane = new InterpChoicePane();
|
||||
Label inteprlabel = new Label("Interpolation");
|
||||
PamGuiManagerFX.titleFont2style(inteprlabel);
|
||||
|
||||
PamHBox interpBox = new PamHBox();
|
||||
interpBox.setSpacing(5);
|
||||
Label interpMethodLabel = new Label("Method");
|
||||
|
||||
Region spacer = new Region();
|
||||
spacer.prefWidthProperty().bind(originButton.widthProperty());
|
||||
interpBox.getChildren().addAll(interpMethodLabel, interpPane, spacer);
|
||||
interpBox.setAlignment(Pos.CENTER_LEFT);
|
||||
interpBox.setMaxWidth(Double.MAX_VALUE);
|
||||
interpPane.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(interpPane, Priority.ALWAYS);
|
||||
|
||||
//add all stuff to the holder
|
||||
PamVBox holder = new PamVBox();
|
||||
holder.getChildren().addAll(label, originHolder, hydroMovementLabel, createLocatorPane(), inteprlabel, interpBox);
|
||||
holder.setSpacing(5);
|
||||
|
||||
|
||||
return holder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the locator pane.
|
||||
* @return the pane containing controls.
|
||||
*/
|
||||
public Pane createLocatorPane() {
|
||||
|
||||
//craet data sources for sensors.
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
sensorComponents = new SensorSourcePane[sensorFields.length];
|
||||
//EnableOrientation eo = new EnableOrientation();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
sensorComponents[i] = new SensorSourcePane(sensorFields[i], true, sensorFields[i] != ArraySensorFieldType.HEIGHT);
|
||||
//sensorComponents[i].addActionListenr(eo);
|
||||
}
|
||||
|
||||
localiserMethod = new ComboBox<>();
|
||||
int n = HydrophoneLocators.getInstance().getCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
localiserMethod.getItems().add(HydrophoneLocators.getInstance().getSystem(i));
|
||||
}
|
||||
localiserMethod.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
PamHBox loclaiserMethodHolder = new PamHBox();
|
||||
loclaiserMethodHolder.setSpacing(5);
|
||||
loclaiserMethodHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
Label spacer = new Label();
|
||||
spacer.prefWidthProperty().bind(originButton.widthProperty());
|
||||
loclaiserMethodHolder.getChildren().addAll(localiserMethod, spacer);
|
||||
loclaiserMethodHolder.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(localiserMethod, Priority.ALWAYS);
|
||||
|
||||
//hydrophone position and
|
||||
PamGridPane positionPane = new PamGridPane();
|
||||
positionPane.setHgap(5);
|
||||
positionPane.setVgap(5);
|
||||
|
||||
ColumnConstraints rc = new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, MAX_TEXTFIELD_WIDTH);
|
||||
|
||||
|
||||
//this sets all text fields to the correct width - but of naff hack but what grid pane needs to work.
|
||||
for (int i=1; i<5; i++) {
|
||||
positionPane.getColumnConstraints().add(rc);
|
||||
}
|
||||
|
||||
xPos=new TextField();
|
||||
xPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(xPos, "x position", validator);
|
||||
yPos=new TextField();
|
||||
yPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(yPos, "y position", validator);
|
||||
zPos=new TextField();
|
||||
zPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(zPos, "z position", validator);
|
||||
|
||||
|
||||
depthLabel = new Label("Depth");
|
||||
depthLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
depthSensorLabel = new Label("Depth Sensor");
|
||||
depthSensorLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
xPosErr=new TextField();
|
||||
xPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(xPosErr, "x error", validator);
|
||||
yPosErr=new TextField();
|
||||
yPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(yPosErr, "y error", validator);
|
||||
zPosErr=new TextField();
|
||||
zPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
depthLabel2 = new Label(""); //changes with air or water mode.
|
||||
depthLabel2.setAlignment(Pos.CENTER);
|
||||
HydrophoneSettingsPane.addTextValidator(zPosErr, "z error", validator);
|
||||
|
||||
int col=0;
|
||||
int row=0;
|
||||
|
||||
|
||||
Label xLabel = new Label("x");
|
||||
xLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label yLabel = new Label("y");
|
||||
yLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
//Orientations
|
||||
|
||||
String degsLab = LatLong.deg + " ";
|
||||
|
||||
|
||||
col=1;
|
||||
positionPane.add(xLabel, col++, row);
|
||||
positionPane.add(yLabel, col++, row);
|
||||
positionPane.add(depthLabel, col++, row);
|
||||
col++;
|
||||
positionPane.add(depthSensorLabel, col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label positionLabel = new Label("Position");
|
||||
positionPane.add(positionLabel, col++, row);
|
||||
positionPane.add(xPos, col++, row);
|
||||
positionPane.add(yPos, col++, row);
|
||||
positionPane.add(zPos, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.HEIGHT.ordinal()].getPane(), col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label errLabel = new Label("Error");
|
||||
positionPane.add(errLabel, col++, row);
|
||||
positionPane.add(xPosErr, col++, row);
|
||||
positionPane.add(yPosErr, col++, row);
|
||||
positionPane.add(zPosErr, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
|
||||
//Orientation
|
||||
col=1;
|
||||
row++;
|
||||
|
||||
Label headingLabel = new Label("Heading");
|
||||
headingLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label pitchLabel = new Label("Pitch");
|
||||
pitchLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label rolllabel = new Label("Roll");
|
||||
rolllabel.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
positionPane.add(headingLabel, col++, row);
|
||||
positionPane.add(pitchLabel, col++, row);
|
||||
positionPane.add(rolllabel, col++, row);
|
||||
|
||||
row++;
|
||||
|
||||
heading = new TextField();
|
||||
heading.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(heading, "heading", validator);
|
||||
|
||||
pitch = new TextField();
|
||||
pitch.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(pitch, "pitch", validator);
|
||||
|
||||
roll = new TextField();
|
||||
roll.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(roll, "roll", validator);
|
||||
|
||||
|
||||
col=0;
|
||||
|
||||
|
||||
Label orientation = new Label("Orientation");
|
||||
positionPane.add(orientation, col++, row);
|
||||
positionPane.add(heading, col++, row);
|
||||
positionPane.add(pitch, col++, row);
|
||||
positionPane.add(roll, col++, row);
|
||||
positionPane.add(new Label(degsLab), col++, row);
|
||||
|
||||
PamButton button = new PamButton("Sensors");
|
||||
button.setGraphic(PamGlyphDude.createPamIcon("mdi2c-compass-outline", PamGuiManagerFX.iconSize));
|
||||
|
||||
PopOver popOver = new PopOver(createSensorPane());
|
||||
popOver.setDetachable(true);
|
||||
|
||||
button.setOnAction((a)->{
|
||||
popOver.show(button);
|
||||
});
|
||||
|
||||
positionPane.add(button, col++, row);
|
||||
|
||||
PamVBox holder= new PamVBox();
|
||||
holder.setSpacing(5);
|
||||
holder.getChildren().addAll(loclaiserMethodHolder, positionPane);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pane to set where sensor data comes from
|
||||
* @return the sensor pane.
|
||||
*/
|
||||
private Pane createSensorPane() {
|
||||
PamBorderPane pane = new PamBorderPane();
|
||||
|
||||
//hydrophone position and
|
||||
PamGridPane positionPane = new PamGridPane();
|
||||
positionPane.setHgap(5);
|
||||
positionPane.setVgap(5);
|
||||
|
||||
int col=0;
|
||||
int row=0;
|
||||
|
||||
positionPane.add(new Label("Heading"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.HEADING.ordinal()].getPane(), col++, row);
|
||||
|
||||
row++;
|
||||
col=0;
|
||||
positionPane.add(new Label("Pitch"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.PITCH.ordinal()].getPane(), col++, row);
|
||||
|
||||
row++;
|
||||
col=0;
|
||||
positionPane.add(new Label("Roll"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.ROLL.ordinal()].getPane(), col++, row);
|
||||
|
||||
Label orientLabel = new Label("Orientation Data");
|
||||
PamGuiManagerFX.titleFont2style(orientLabel);
|
||||
|
||||
pane.setTop(orientLabel);
|
||||
pane.setCenter(positionPane);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new origin method.
|
||||
*/
|
||||
public void newOriginMethod() {
|
||||
|
||||
int methInd = originMethod.getSelectionModel().getSelectedIndex();
|
||||
if (methInd < 0) {
|
||||
return;
|
||||
}
|
||||
HydrophoneOriginSystem currentSystem = HydrophoneOriginMethods.getInstance().getMethod(this.originMethod.getSelectionModel().getSelectedIndex());
|
||||
currentOriginMethod = currentSystem.createMethod(currentArray, defaultStreamer);
|
||||
try {
|
||||
OriginSettings os = defaultStreamer.getOriginSettings(currentOriginMethod.getClass());
|
||||
if (os != null) {
|
||||
currentOriginMethod.setOriginSettings(os);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// will throw if it tries to set the wrong type of settings.
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
|
||||
|
||||
if (mthDialogComponent == null) {
|
||||
originPanel.getChildren().clear();
|
||||
currentOriginComponent = null;
|
||||
this.originButton.setDisable(true);
|
||||
}
|
||||
else {
|
||||
this.originButton.setDisable(false);
|
||||
Pane newComponent = mthDialogComponent.getSettingsPane();
|
||||
if (currentOriginComponent != newComponent) {
|
||||
originPanel.setCenter(newComponent);
|
||||
currentOriginComponent = newComponent;
|
||||
mthDialogComponent.setParams();
|
||||
}
|
||||
}
|
||||
enableControls();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void enableControls() {
|
||||
if (currentOriginMethod != null) {
|
||||
interpPane.setAllowedValues(currentOriginMethod.getAllowedInterpolationMethods());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Streamer getParams(Streamer currParams) {
|
||||
|
||||
try {
|
||||
defaultStreamer.setX(Double.valueOf(xPos.getText()));
|
||||
defaultStreamer.setY(Double.valueOf(yPos.getText()));
|
||||
defaultStreamer.setZ(-Double.valueOf(zPos.getText()));
|
||||
defaultStreamer.setDx(Double.valueOf(xPosErr.getText()));
|
||||
defaultStreamer.setDy(Double.valueOf(yPosErr.getText()));
|
||||
defaultStreamer.setDz(Double.valueOf(zPosErr.getText()));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
System.err.println("Streamer getParams: There is a problem with one of the position parameters in the streamer panel");
|
||||
return null;
|
||||
}
|
||||
|
||||
defaultStreamer.setStreamerName(currParams.getStreamerName());
|
||||
int im = interpPane.getSelection();
|
||||
if (im < 0) {
|
||||
System.err.println("Streamer getParams: There is an index problem with the interpolation selection streamer panel: index = " + im);
|
||||
}
|
||||
currentArray.setOriginInterpolation(im);
|
||||
// try {
|
||||
// streamer.setBuoyId1(Integer.valueOf(buoyId.getText()));
|
||||
// }
|
||||
// catch (NumberFormatException e) {
|
||||
// streamer.setBuoyId1(null);
|
||||
// }
|
||||
HydrophoneLocator locator = HydrophoneLocators.getInstance().
|
||||
getSystem(localiserMethod.getSelectionModel().getSelectedIndex()).getLocator(currentArray, defaultStreamer);
|
||||
if (originPanel != null)
|
||||
// MasterLocator masterLocator = currentArray.getMasterLocator();
|
||||
// int streamerIndex = currentArray.indexOfStreamer(streamer);
|
||||
// if (streamerIndex < 0) {
|
||||
// streamerIndex = currentArray.getNumStreamers();
|
||||
// }
|
||||
// masterLocator.setHydrophoneLocator(streamerIndex, locator);
|
||||
if (currentOriginMethod == null) {
|
||||
System.err.println("Streamer getParams: No hydrophoneorigin method selected in streamer panel");
|
||||
}
|
||||
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
|
||||
if (mthDialogComponent != null) {
|
||||
if (mthDialogComponent.getParams() == false) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// defaultStreamer.setEnableOrientation(enableOrientation.isSelected());
|
||||
// if (enableOrientation.isSelected()) {
|
||||
defaultStreamer.setHeading(getDoubleValue(heading));
|
||||
defaultStreamer.setPitch(getDoubleValue(pitch));
|
||||
defaultStreamer.setRoll(getDoubleValue(roll));
|
||||
// }
|
||||
if (!heading.isDisable() && defaultStreamer.getHeading() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer heading");
|
||||
}
|
||||
if (!pitch.isDisable() && defaultStreamer.getPitch() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer pitch");
|
||||
}
|
||||
if (!roll.isDisable() && defaultStreamer.getRoll() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer roll");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We may have large lists of the streamers which we mwant to use the orientation data from or not. The enable orientation check box will
|
||||
* enable or disable orientation for ALL streamers which are loaded into memory.
|
||||
*/
|
||||
// setEnableRotation(enableOrientation.isSelected(), defaultStreamer.getStreamerIndex());
|
||||
|
||||
defaultStreamer.setHydrophoneOrigin(currentOriginMethod);
|
||||
defaultStreamer.setHydrophoneLocator(locator);
|
||||
defaultStreamer.setOriginSettings(currentOriginMethod.getOriginSettings());
|
||||
defaultStreamer.setLocatorSettings(locator.getLocatorSettings());
|
||||
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
ArrayParameterType fieldType = sensorComponents[i].getParameterType();
|
||||
defaultStreamer.setOrientationTypes(sensorFields[i], fieldType);
|
||||
if (fieldType == ArrayParameterType.SENSOR) {
|
||||
PamDataBlock dataBlock = sensorComponents[i].getDataBlock();
|
||||
defaultStreamer.setSensorDataBlocks(sensorFields[i], dataBlock == null ? null : dataBlock.getLongDataName());
|
||||
}
|
||||
}
|
||||
|
||||
return defaultStreamer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(Streamer input) {
|
||||
if (input==null) {
|
||||
System.out.print("Streamer setParams: The input streamer is null");
|
||||
}
|
||||
this.defaultStreamer=input;
|
||||
// origin methods
|
||||
// MasterLocator masterLocator = currentArray.getMasterLocator();
|
||||
// int streamerIndex = currentArray.indexOfStreamer(streamer);
|
||||
HydrophoneLocator hLocator = defaultStreamer.getHydrophoneLocator();
|
||||
if (hLocator != null) {
|
||||
int locatorIndex = HydrophoneLocators.getInstance().indexOfClass(hLocator.getClass());
|
||||
localiserMethod.getSelectionModel().select(locatorIndex);
|
||||
|
||||
HydrophoneOriginMethod originMethod = defaultStreamer.getHydrophoneOrigin();
|
||||
if (originMethod != null) {
|
||||
int originIndex = HydrophoneOriginMethods.getInstance().indexOfClass(originMethod.getClass());
|
||||
this.originMethod.getSelectionModel().select(originIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
localiserMethod.getSelectionModel().select(0);
|
||||
}
|
||||
|
||||
// streamerName.setText(defaultStreamer.getStreamerName());
|
||||
|
||||
xPos.setText(String.valueOf(defaultStreamer.getX()));
|
||||
yPos.setText(String.valueOf(defaultStreamer.getY()));
|
||||
zPos.setText(String.valueOf(PamController.getInstance().getGlobalMediumManager().getZCoeff()*defaultStreamer.getZ()));
|
||||
xPosErr.setText(String.valueOf(defaultStreamer.getDx()));
|
||||
yPosErr.setText(String.valueOf(defaultStreamer.getDy()));
|
||||
zPosErr.setText(String.valueOf(defaultStreamer.getDz()));
|
||||
// if (streamer.getBuoyId1() != null) {
|
||||
// buoyId.setText(streamer.getBuoyId1().toString());
|
||||
// }
|
||||
// else {
|
||||
// buoyId.setText("");
|
||||
// }
|
||||
|
||||
HydrophoneOriginMethod mth = defaultStreamer.getHydrophoneOrigin();
|
||||
if (mth==null) {
|
||||
originMethod.getSelectionModel().select(0);
|
||||
newOriginMethod();
|
||||
mth = currentOriginMethod;
|
||||
//defaultStreamer.setHydrophoneOrigin(HydrophoneOriginMethods.getInstance().getMethod(0).createMethod(currentArray, defaultStreamer));
|
||||
}
|
||||
|
||||
|
||||
OriginDialogComponent mthDialogComponent = mth.getDialogComponent();
|
||||
if (mthDialogComponent != null) {
|
||||
System.out.println("Streamer setParams: Set origin component: ");
|
||||
mthDialogComponent.setParams();
|
||||
}
|
||||
|
||||
System.out.println("Streamer setParams: Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll());
|
||||
|
||||
heading .setText(orientation2Text(defaultStreamer.getHeading()));
|
||||
pitch .setText(orientation2Text(defaultStreamer.getPitch()));
|
||||
roll .setText(orientation2Text(defaultStreamer.getRoll()));
|
||||
|
||||
System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation());
|
||||
|
||||
if (currentArray.getOriginInterpolation()<0) {
|
||||
interpPane.setSelection(0);
|
||||
}
|
||||
else {
|
||||
interpPane.setSelection(currentArray.getOriginInterpolation());
|
||||
}
|
||||
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
ArrayParameterType fieldType = defaultStreamer.getOrientationTypes(sensorFields[i]);
|
||||
String fieldDataBlock = defaultStreamer.getSensorDataBlocks(sensorFields[i]);
|
||||
sensorComponents[i].setParameterType(fieldType);
|
||||
if (fieldType == ArrayParameterType.SENSOR && fieldDataBlock != null) {
|
||||
sensorComponents[i].setDataBlock(PamController.getInstance().getDataBlockByLongName(fieldDataBlock));
|
||||
}
|
||||
}
|
||||
|
||||
setRecieverLabels() ;
|
||||
enableControls();
|
||||
|
||||
}
|
||||
|
||||
private String orientation2Text(Double ang) {
|
||||
if (ang == null) return String.valueOf(0.0);
|
||||
else return String.format("%3.1f", defaultStreamer.getHeading());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Streamer Pane";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
private Double getDoubleValue(TextField textField) {
|
||||
String txt = textField.getText();
|
||||
if (txt == null || txt.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
Double val;
|
||||
try {
|
||||
val = Double.valueOf(txt);
|
||||
return val;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
System.err.println("Invalid orientation information: " + txt);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentArray(PamArray currentArray2) {
|
||||
this.currentArray=currentArray2;
|
||||
|
||||
}
|
||||
}
|
208
src/Array/layoutFX/StreamersPane.java
Normal file
208
src/Array/layoutFX/StreamersPane.java
Normal file
@ -0,0 +1,208 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import PamController.PamController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.Dialog;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.flipPane.PamFlipPane;
|
||||
import pamViewFX.fxNodes.table.TableSettingsPane;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
/**
|
||||
* A pane for setting up hydrophones. Note that this is entirely separate from PAMGuard so can be used in
|
||||
* other projects.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class StreamersPane extends PamBorderPane {
|
||||
|
||||
BasicArrayTable tableArrayPane;
|
||||
|
||||
ObservableList<StreamerProperty> streamerData = FXCollections.observableArrayList();
|
||||
|
||||
/**
|
||||
* The current hydrophone array
|
||||
*/
|
||||
private PamArray currentArray;
|
||||
|
||||
/**
|
||||
* The pam flip pane.
|
||||
*/
|
||||
private PamFlipPane pamFlipePane;
|
||||
|
||||
/**
|
||||
* The current streamer data.
|
||||
*/
|
||||
private StreamerProperty currentStreamerData;
|
||||
|
||||
/**
|
||||
* Settings pane for a single hydrophone.
|
||||
*/
|
||||
private StreamerSettingsPane streamerPane = new StreamerSettingsPane();
|
||||
|
||||
|
||||
public StreamersPane() {
|
||||
|
||||
tableArrayPane = new BasicArrayTable(streamerData);
|
||||
|
||||
tableArrayPane.setPadding(new Insets(5,5,5,5));
|
||||
this.setCenter(tableArrayPane);
|
||||
|
||||
pamFlipePane = new PamFlipPane();
|
||||
pamFlipePane.getAdvLabel().setText("Streamer");
|
||||
|
||||
((Pane) streamerPane.getContentNode()).setPadding(new Insets(5,5,5,15));
|
||||
|
||||
pamFlipePane.setAdvPaneContent(streamerPane.getContentNode());
|
||||
pamFlipePane.setFrontContent(tableArrayPane);
|
||||
|
||||
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
|
||||
pamFlipePane.setAdvLabelEditable(true);
|
||||
pamFlipePane.getPostAdvLabel().setText("Settings");
|
||||
|
||||
pamFlipePane.flipFrontProperty().addListener((obsval, oldVal, newVal)->{
|
||||
//the flip pane
|
||||
if (newVal) {
|
||||
Streamer streamer = streamerPane.getParams(currentStreamerData.getStreamer());
|
||||
|
||||
if (streamer==null) {
|
||||
//the warning dialog is shown in the streamer settings pane
|
||||
return;
|
||||
}
|
||||
|
||||
streamer.setStreamerName(pamFlipePane.getAdvLabel().getText());
|
||||
|
||||
currentStreamerData.setStreamer(streamer);
|
||||
|
||||
//need to refresh table to show symbol.
|
||||
tableArrayPane.getTableView().refresh();
|
||||
}
|
||||
});
|
||||
|
||||
this.setCenter(pamFlipePane);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
class BasicArrayTable extends TableSettingsPane<StreamerProperty> {
|
||||
|
||||
private TableColumn<StreamerProperty, Number> z;
|
||||
|
||||
|
||||
public BasicArrayTable(ObservableList<StreamerProperty> data) {
|
||||
super(data);
|
||||
//need to set up all the rows.
|
||||
TableColumn<StreamerProperty,Number> streamerID = new TableColumn<StreamerProperty,Number>("ID");
|
||||
streamerID.setCellValueFactory(cellData -> cellData.getValue().getID());
|
||||
streamerID.setEditable(false);
|
||||
|
||||
TableColumn<StreamerProperty,String> name = new TableColumn<StreamerProperty,String>("Name");
|
||||
name.setCellValueFactory(cellData -> cellData.getValue().getName());
|
||||
name.setEditable(true);
|
||||
|
||||
|
||||
TableColumn<StreamerProperty,Number> x = new TableColumn<StreamerProperty,Number>("x");
|
||||
x.setCellValueFactory(cellData -> cellData.getValue().getX());
|
||||
x.setEditable(false);
|
||||
|
||||
TableColumn<StreamerProperty,Number> y = new TableColumn<StreamerProperty,Number>("y");
|
||||
y.setCellValueFactory(cellData -> cellData.getValue().getY());
|
||||
y.setEditable(false);
|
||||
|
||||
z = new TableColumn<StreamerProperty,Number>("depth");
|
||||
z.setCellValueFactory(cellData -> cellData.getValue().getZ());
|
||||
z.setEditable(false);
|
||||
|
||||
TableColumn posColumn=new TableColumn("Position (m)");
|
||||
posColumn.getColumns().addAll(x, y, z);
|
||||
|
||||
TableColumn<StreamerProperty,String> reference = new TableColumn<StreamerProperty,String>("Reference");
|
||||
reference.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
|
||||
reference.setEditable(true);
|
||||
|
||||
TableColumn<StreamerProperty,String> locator = new TableColumn<StreamerProperty,String>("Locator");
|
||||
locator.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
|
||||
locator.setEditable(true);
|
||||
|
||||
TableColumn geoColumn=new TableColumn("Geo-reference");
|
||||
geoColumn.getColumns().addAll(reference, locator);
|
||||
|
||||
|
||||
getTableView().getColumns().addAll(streamerID, name, posColumn, geoColumn);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dialogClosed(StreamerProperty data) {
|
||||
Streamer hydro = streamerPane.getParams(data.getStreamer());
|
||||
data.setStreamer(hydro);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog<StreamerProperty> createSettingsDialog(StreamerProperty data) {
|
||||
//we do not use dialogs here- sliding pane instead.
|
||||
// setClassifierPane(data);
|
||||
// showFlipPane(true);
|
||||
pamFlipePane.flipToBack();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editData(StreamerProperty data){
|
||||
|
||||
if (data.getName() == null){
|
||||
pamFlipePane.getAdvLabel().setText("Streamer " + data.getID().get());
|
||||
|
||||
}
|
||||
|
||||
streamerPane.setCurrentArray(currentArray);
|
||||
streamerPane.setParams(data.getStreamer());
|
||||
|
||||
currentStreamerData = data;
|
||||
|
||||
pamFlipePane.flipToBack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNewData(){
|
||||
//create a new classifier.
|
||||
streamerData.add(createDefaultStreamerProperty());
|
||||
}
|
||||
|
||||
private StreamerProperty createDefaultStreamerProperty() {
|
||||
Streamer streamer = new Streamer(1, 0.,0.,0.,0.,0.,0.);
|
||||
return new StreamerProperty(streamer);
|
||||
}
|
||||
|
||||
public TableColumn<StreamerProperty, Number> getZColumn() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setParams(PamArray currentArray) {
|
||||
this.currentArray=currentArray;
|
||||
}
|
||||
|
||||
public PamArray getParams(PamArray currParams) {
|
||||
return currParams;
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
tableArrayPane.getZColumn().setText(PamController.getInstance().getGlobalMediumManager().getZString());
|
||||
streamerPane.setRecieverLabels();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -27,7 +27,7 @@ public class PamArrayUtils {
|
||||
* @param dim - the dimension of the point to calculate the average for
|
||||
* @return the mean of one dimension of the list of the points.
|
||||
*/
|
||||
public static double mean(ArrayList<double[]> array, double InitialtoIgnorePercentage, int dim){
|
||||
public static double mean(ArrayList<float[]> array, double InitialtoIgnorePercentage, int dim){
|
||||
|
||||
double meanTotal=0;
|
||||
int n=0;
|
||||
@ -42,6 +42,7 @@ public class PamArrayUtils {
|
||||
double mean=meanTotal/n;
|
||||
return mean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the standard deviation of an array of doubles, ignoring an 'initialtoIgnorePercentage' percentage of jumps
|
||||
@ -49,7 +50,7 @@ public class PamArrayUtils {
|
||||
* @param initialtoIgnorePercentage- percentage of initial values to ignore.
|
||||
* @return standard deviation of array.
|
||||
*/
|
||||
public static double std(ArrayList<double[]> array, double initialtoIgnorePercentage, int dim){
|
||||
public static double std(ArrayList<float[]> array, double initialtoIgnorePercentage, int dim){
|
||||
double std=0.0;
|
||||
|
||||
int n=0;
|
||||
@ -448,19 +449,6 @@ public class PamArrayUtils {
|
||||
return new int[] {min, max};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the maximum value in an array
|
||||
* @param arr - the array to find the maximum value of.
|
||||
* @return the maximum value in the array
|
||||
*/
|
||||
public static double max(double[] arr) {
|
||||
double max = Double.NEGATIVE_INFINITY;
|
||||
|
||||
for(double cur: arr)
|
||||
max = Math.max(max, cur);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the maximum value in an array
|
||||
@ -475,6 +463,20 @@ public class PamArrayUtils {
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the maximum value in an array
|
||||
* @param arr - the array to find the maximum value of.
|
||||
* @return the maximum value in the array
|
||||
*/
|
||||
public static double max(double[] arr) {
|
||||
double max = Double.NEGATIVE_INFINITY;
|
||||
|
||||
for(double cur: arr)
|
||||
max = Math.max(max, cur);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the maximum value in an array
|
||||
@ -489,6 +491,50 @@ public class PamArrayUtils {
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the maximum value in an array
|
||||
* @param arr - the array to find the position of the maximum value.
|
||||
* m value of.
|
||||
* @return the index of the maximum value
|
||||
*/
|
||||
public static int maxPos(double[] arr) {
|
||||
double max = Double.NEGATIVE_INFINITY;
|
||||
int index = -1;
|
||||
|
||||
int count = 0;
|
||||
for(double cur: arr) {
|
||||
if (cur>max) {
|
||||
index = count;
|
||||
max=cur;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum index of an array
|
||||
* @param arr - the array to find the position of the maximum value.
|
||||
* m value of.
|
||||
* @return the index of the minimum value
|
||||
*/
|
||||
public static int minPos(double[] arr) {
|
||||
double max = Double.POSITIVE_INFINITY;
|
||||
int index = -1;
|
||||
|
||||
int count = 0;
|
||||
for(double cur: arr) {
|
||||
if (cur<max) {
|
||||
index = count;
|
||||
max=cur;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum value in an array
|
||||
@ -504,6 +550,8 @@ public class PamArrayUtils {
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the minimum value in an array
|
||||
@ -578,6 +626,27 @@ public class PamArrayUtils {
|
||||
ArrayUtils.reverse(clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split an array based on start index and end index. A new array with index 0
|
||||
* as start and the last index at end is created and data from the input array
|
||||
* copied to it.
|
||||
*
|
||||
* @param arr - the array to split
|
||||
* @param start - the start index
|
||||
* @param end - the end index
|
||||
* @return the split array.
|
||||
*/
|
||||
public static double[][] split(double[][] arr, int start, int end) {
|
||||
double[][] newArr = new double[end - start][];
|
||||
int n = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
newArr[n] = arr[i];
|
||||
n++;
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sum the elements in an array
|
||||
@ -855,5 +924,151 @@ public class PamArrayUtils {
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 2D float array to a 2D double array.
|
||||
* @param arrf - the float array
|
||||
* @return a double array containing the same numbers as arrf.
|
||||
*/
|
||||
public static double[][] float2Double(float[][] arrf) {
|
||||
double[][] newArray = new double[arrf.length][];
|
||||
for (int i=0; i<arrf.length; i++) {
|
||||
newArray[i] = float2Double(arrf[i]);
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a float array to a double array.
|
||||
* @param arrd - the double array
|
||||
* @return a double array containing the same numbers as arrf.
|
||||
*/
|
||||
public static float[] double2Float(double[] arrd) {
|
||||
float[] arr = new float[arrd.length];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arr[i] = (float) arrd[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 2D float array to a 2D double array.
|
||||
* @param arrd - the double array
|
||||
* @return a double array containing the same numbers as arrf.
|
||||
*/
|
||||
public static float[][] double2Float(double[][] arrd) {
|
||||
float[][] newArray = new float[arrd.length][];
|
||||
for (int i=0; i<arrd.length; i++) {
|
||||
newArray[i] = double2Float(arrd[i]);
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if two int arrays contain the same elements
|
||||
* @param arr1 - the array to compare to.
|
||||
* @param arr2 - the array to be compared.
|
||||
*/
|
||||
public static boolean arrEquals(int[] arr1, int[] arr2) {
|
||||
if (arr1.length!=arr2.length) return false;
|
||||
|
||||
for (int i =0 ;i<arr1.length; i++) {
|
||||
if (arr1[i]!=arr2[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two double arrays contain the same elements
|
||||
* @param arr1 - the array to compare to.
|
||||
* @param arr2 - the array to be compared.
|
||||
*/
|
||||
public static boolean arrEquals(double[] arr1, double[] arr2) {
|
||||
if (arr1.length!=arr2.length) return false;
|
||||
|
||||
for (int i =0 ;i<arr1.length; i++) {
|
||||
if (arr1[i]!=arr2[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert primitive long array to Long object array.
|
||||
* @param arr - primitive long array
|
||||
* @return a Long array
|
||||
*/
|
||||
public static Long[] primitive2Object(long[] arr) {
|
||||
if (arr==null) return null;
|
||||
|
||||
Long[] arrL = new Long[arr.length];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arrL[i]=arr[i];
|
||||
}
|
||||
return arrL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert primitive double array to Double object array.
|
||||
* @param arr - primitive double array
|
||||
* @return a Double array
|
||||
*/
|
||||
public static Double[] primitive2Object(double[] arr) {
|
||||
if (arr==null) return null;
|
||||
|
||||
Double[] arrL = new Double[arr.length];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arrL[i]=arr[i];
|
||||
}
|
||||
return arrL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert primitive int array to Integer object array.
|
||||
* @param arr - primitive int array
|
||||
* @return a Ineteger array
|
||||
*/
|
||||
public static Integer[] primitive2Object(int[] arr) {
|
||||
if (arr==null) return null;
|
||||
|
||||
Integer[] arrL = new Integer[arr.length];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arrL[i]=arr[i];
|
||||
}
|
||||
return arrL;
|
||||
}
|
||||
|
||||
|
||||
public static long[] object2Primitve(Long[] arr) {
|
||||
if (arr==null) return null;
|
||||
|
||||
long[] arrL = new long[arr.length];
|
||||
for (int i=0; i<arr.length; i++) {
|
||||
arrL[i]=arr[i].longValue();
|
||||
}
|
||||
return arrL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
@ -89,10 +90,20 @@ public class TxtFileUtils {
|
||||
//5/08/2022 - there was a bug here where there is some sort of invisible character that does not appear on the
|
||||
//print screen - the only way you can tell is the char array is greater than the number of digits - removed all non numeric
|
||||
//characters.
|
||||
// updated again on 15/11/23 to include - signs, or you end up with the abs(of every number!)
|
||||
String number = new String(recordsOnLine[i].strip().replaceAll("[^\\d.-]", ""));
|
||||
dat = Double.valueOf(number);
|
||||
//dat = DecimalFormat.getNumberInstance().parse(new String(recordsOnLine[i].strip().toCharArray())).doubleValue();
|
||||
|
||||
// if (recordsOnLine[i].contains("e") || recordsOnLine[i].contains("E")) {
|
||||
// //need to check whether scientific notation might be used here
|
||||
//// dat = new BigDecimal(recordsOnLine[i]).doubleValue();
|
||||
// dat = Double.valueOf(recordsOnLine[i]);
|
||||
// }
|
||||
// else {
|
||||
//note that this gets rid of numbers like 3.84e+05
|
||||
// updated again on 15/11/23 to include - signs, or you end up with the abs(of every number!)
|
||||
//also added E and e to neglected characters to ensure scientific notation can be used,
|
||||
String number = new String(recordsOnLine[i].strip().replaceAll("[^Ee\\d.-]", ""));
|
||||
dat = Double.valueOf(number);
|
||||
//dat = DecimalFormat.getNumberInstance().parse(new String(recordsOnLine[i].strip().toCharArray())).doubleValue();
|
||||
// }
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
|
@ -395,7 +395,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
|
||||
int subDetInd = superDet.findSubdetectionInfo(clickDetection);
|
||||
for (int i = subDetInd-1; i >= 0; i--) {
|
||||
PamDataUnit subDet = superDet.getSubDetection(i);
|
||||
if (subDet.getChannelBitmap() == clickDetection.getChannelBitmap()) {
|
||||
if (subDet!=null && subDet.getChannelBitmap() == clickDetection.getChannelBitmap()) {
|
||||
double ici = (double) (clickDetection.getTimeMilliseconds() - subDet.getTimeMilliseconds())/1000.;
|
||||
clickDetection.setTempICI(ici);
|
||||
break;
|
||||
|
@ -1,13 +1,18 @@
|
||||
package clickDetector.layoutFX.clickClassifiers;
|
||||
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamSymbolFX;
|
||||
import pamViewFX.fxNodes.flipPane.PamFlipPane;
|
||||
import pamViewFX.fxNodes.table.TableSettingsPane;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Dialog;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.cell.CheckBoxTableCell;
|
||||
import clickDetector.BasicClickIdParameters;
|
||||
@ -15,6 +20,7 @@ import clickDetector.ClickControl;
|
||||
import clickDetector.ClickTypeParams;
|
||||
import clickDetector.ClickClassifiers.ClickIdentifier;
|
||||
import clickDetector.ClickClassifiers.basic.BasicClickIdentifier;
|
||||
import clickDetector.ClickClassifiers.basicSweep.*;
|
||||
|
||||
/**
|
||||
* Pane for the basic click classifier.
|
||||
@ -23,33 +29,33 @@ import clickDetector.ClickClassifiers.basic.BasicClickIdentifier;
|
||||
*
|
||||
*/
|
||||
public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
|
||||
|
||||
/**
|
||||
* Reference to the basicClickIdentifier.
|
||||
*/
|
||||
private ClickIdentifier basicClickIdentifier;
|
||||
|
||||
|
||||
/**
|
||||
* Reference to the click control.
|
||||
*/
|
||||
protected ClickControl clickControl;
|
||||
|
||||
|
||||
/**
|
||||
* Pane which holds table data.
|
||||
*/
|
||||
private TableSettingsPane<ClickTypeProperty> settingsPane;
|
||||
|
||||
// /**
|
||||
// * Hiding pane which slides out to allow users to change click type settings.
|
||||
// */
|
||||
// protected HidingPane hidingPane;
|
||||
|
||||
protected TableSettingsPane<ClickTypeProperty> clickTypesTable;
|
||||
|
||||
// /**
|
||||
// * Hiding pane which slides out to allow users to change click type settings.
|
||||
// */
|
||||
// protected HidingPane hidingPane;
|
||||
|
||||
/**
|
||||
* Holds click classifier controls inside hiding pane.
|
||||
*/
|
||||
protected PamBorderPane clickTypeHolder;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A list of click classifiers currently shown in the table.It Would have been much easier to have this in params
|
||||
* but didn't want to add any FX related as these should be GUI independent classes.
|
||||
@ -60,19 +66,19 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
* Holds the table.
|
||||
*/
|
||||
protected PamBorderPane mainHolderPane;
|
||||
|
||||
// /**
|
||||
// * The width of the hiding pane
|
||||
// */
|
||||
// private double hidingPaneWidth=900;
|
||||
|
||||
// /**
|
||||
// * The width of the hiding pane
|
||||
// */
|
||||
// private double hidingPaneWidth=900;
|
||||
|
||||
/**
|
||||
* Cloned copy of BasicClickIdParameters.
|
||||
*/
|
||||
private BasicClickIdParameters basicClickIdParameters;
|
||||
|
||||
|
||||
private PamBorderPane mainPane;
|
||||
|
||||
|
||||
private PamFlipPane flipPane;
|
||||
|
||||
/**
|
||||
@ -85,7 +91,7 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
this.basicClickIdentifier= basicClickIdentifier;
|
||||
this.clickControl=clickControl;
|
||||
mainPane= new PamBorderPane();
|
||||
|
||||
|
||||
flipPane = new PamFlipPane();
|
||||
flipPane.getFrontPane().setCenter(createSettingsPane());
|
||||
flipPane.getBackPane().setCenter(clickTypeHolder);
|
||||
@ -93,35 +99,36 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
mainPane.setCenter(flipPane);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the controls for the basic click identifier pane.
|
||||
* @return node with all controls for basic click classifier.
|
||||
*/
|
||||
protected Node createSettingsPane(){
|
||||
|
||||
|
||||
mainHolderPane=new PamBorderPane();
|
||||
mainHolderPane.setCenter(settingsPane=new ClickClassifierTable(clickClassifiers));
|
||||
|
||||
mainHolderPane.setPadding(new Insets(5,5,5,5));
|
||||
mainHolderPane.setCenter(clickTypesTable=new ClickClassifierTable(clickClassifiers));
|
||||
|
||||
clickTypeHolder=new PamBorderPane();
|
||||
//clickTypeHolder.setPrefWidth(hidingPaneWidth);
|
||||
|
||||
|
||||
return mainHolderPane;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Added purely so can be override and hiding pane set in different location if required
|
||||
// */
|
||||
// public void createHidingPane(){
|
||||
// hidingPane=new HidingPane(Side.RIGHT, clickTypeHolder, mainPane, false);
|
||||
// //hidingPane.showHidePane(false);
|
||||
// mainHolderPane.setRight(hidingPane);
|
||||
// hidingPane.showHidePane(false);
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * Added purely so can be override and hiding pane set in different location if required
|
||||
// */
|
||||
// public void createHidingPane(){
|
||||
// hidingPane=new HidingPane(Side.RIGHT, clickTypeHolder, mainPane, false);
|
||||
// //hidingPane.showHidePane(false);
|
||||
// mainHolderPane.setRight(hidingPane);
|
||||
// hidingPane.showHidePane(false);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@ -133,7 +140,7 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
public void setParams() {
|
||||
basicClickIdParameters = ((BasicClickIdentifier) basicClickIdentifier).getIdParameters().clone();
|
||||
//change the observable list.
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,9 +158,9 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
@Override
|
||||
public void setActive(boolean b) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
|
||||
* @author Jamie Macaulay
|
||||
@ -164,33 +171,43 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
public ClickClassifierTable(ObservableList<ClickTypeProperty> data) {
|
||||
super(data);
|
||||
//need to set up all the rows.
|
||||
|
||||
TableColumn<ClickTypeProperty,String> name = new TableColumn<ClickTypeProperty,String>("Name");
|
||||
name.setCellValueFactory(cellData -> cellData.getValue().name);
|
||||
name.setEditable(true);
|
||||
|
||||
|
||||
TableColumn<ClickTypeProperty,String> icon = new TableColumn<ClickTypeProperty,String>("Name");
|
||||
icon.setCellValueFactory(cellData -> cellData.getValue().name);
|
||||
icon.setEditable(false);
|
||||
|
||||
icon.setCellFactory((tableColumn) -> {
|
||||
TableCell<ClickTypeProperty, String> tableCell = new ClickTypeNameCell();
|
||||
return tableCell;
|
||||
});
|
||||
|
||||
// TableColumn<ClickTypeProperty,String> name = new TableColumn<ClickTypeProperty,String>("Name");
|
||||
// name.setCellValueFactory(cellData -> cellData.getValue().name);
|
||||
// name.setEditable(true);
|
||||
|
||||
|
||||
TableColumn<ClickTypeProperty,Number> code = new TableColumn<ClickTypeProperty,Number>("Species Code");
|
||||
code.setCellValueFactory(cellData -> cellData.getValue().code);
|
||||
|
||||
|
||||
|
||||
TableColumn<ClickTypeProperty,Boolean> checkCol = new TableColumn<>("Enable");
|
||||
checkCol.setCellValueFactory( cellData -> cellData.getValue().enableClassifier);
|
||||
checkCol.setCellFactory(CheckBoxTableCell.forTableColumn(checkCol));
|
||||
checkCol.setEditable(true);
|
||||
checkCol.setMaxWidth( 100 );
|
||||
checkCol.setMinWidth( 100 );
|
||||
|
||||
|
||||
|
||||
|
||||
TableColumn<ClickTypeProperty,Boolean> discard = new TableColumn<>("Discard");
|
||||
discard.setCellValueFactory( cellData -> cellData.getValue().discardClassifier);
|
||||
discard.setCellFactory(CheckBoxTableCell.forTableColumn(checkCol));
|
||||
discard.setEditable(true);
|
||||
discard.setMaxWidth( 100 );
|
||||
discard.setMinWidth( 100 );
|
||||
|
||||
|
||||
getTableView().setEditable(true);
|
||||
|
||||
getTableView().getColumns().addAll(checkCol, name, code, discard);
|
||||
|
||||
getTableView().getColumns().addAll(checkCol, icon, code, discard);
|
||||
|
||||
}
|
||||
|
||||
@ -206,33 +223,33 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
showFlipPane(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void editData(ClickTypeProperty data){
|
||||
setClassifierPane(data);
|
||||
showFlipPane(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createNewData(){
|
||||
//create a new classifier.
|
||||
clickClassifiers.add(createClickTypeProperty());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Show the hiding pane which contains classifier settings
|
||||
// * NOTE: needed to add this to stop a stack overflow error in BasicClickIdentifier 06/09/2016
|
||||
// * @param show - true to show pane.
|
||||
// */
|
||||
// public void showHidingPane(boolean show){
|
||||
// if (hidingPane==null){
|
||||
// this.createHidingPane();
|
||||
// }
|
||||
// hidingPane.showHidePane(true);
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * Show the hiding pane which contains classifier settings
|
||||
// * NOTE: needed to add this to stop a stack overflow error in BasicClickIdentifier 06/09/2016
|
||||
// * @param show - true to show pane.
|
||||
// */
|
||||
// public void showHidingPane(boolean show){
|
||||
// if (hidingPane==null){
|
||||
// this.createHidingPane();
|
||||
// }
|
||||
// hidingPane.showHidePane(true);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Show the flip pane.
|
||||
* NOTE: needed to add this to stop a stack overflow error in BasicClickIdentifier 06/09/2016
|
||||
@ -247,33 +264,34 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
flipPane.flipToFront();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create click classifier.
|
||||
*/
|
||||
public ClickTypeProperty createClickTypeProperty(){
|
||||
return new ClickTypeProperty(new ClickTypeParams(clickClassifiers.size()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set classifier pane within hiding pane.
|
||||
* @param clickTypeProperty
|
||||
*/
|
||||
public void setClassifierPane(ClickTypeProperty clickTypeProperty){
|
||||
|
||||
|
||||
|
||||
ClickTypePaneFX clickTypePane=new ClickTypePaneFX();
|
||||
clickTypePane.setParams(clickTypeProperty);
|
||||
|
||||
|
||||
clickTypeHolder.setCenter(clickTypePane.getContentNode());
|
||||
|
||||
|
||||
//now need to make sure on closing the pane that settings are saved. Need to
|
||||
//remove the old click type from the list and add new one in the same position.
|
||||
getFlipPaneCloseButton().setOnAction((action)->{
|
||||
//System.out.println("CLOSE FLIP PANE");
|
||||
showFlipPane(false);
|
||||
//this should update the click type property in the observable list thus changing the table
|
||||
clickTypePane.getParams(clickTypeProperty);
|
||||
|
||||
//need to refresh table to show symbol.
|
||||
clickTypesTable.getTableView().refresh();
|
||||
});
|
||||
}
|
||||
|
||||
@ -285,16 +303,16 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
return flipPane.getBackButton();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the hiding pane which holds settings for different click types.
|
||||
// * @return the HidingPane for click classifiers.
|
||||
// */
|
||||
// public HidingPane getClickTypeHidingPane() {
|
||||
// if (hidingPane==null) {
|
||||
// this.createHidingPane();
|
||||
// }
|
||||
// return hidingPane;
|
||||
// }
|
||||
// /**
|
||||
// * Get the hiding pane which holds settings for different click types.
|
||||
// * @return the HidingPane for click classifiers.
|
||||
// */
|
||||
// public HidingPane getClickTypeHidingPane() {
|
||||
// if (hidingPane==null) {
|
||||
// this.createHidingPane();
|
||||
// }
|
||||
// return hidingPane;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the pane which holds the ClickTypePaneFX.
|
||||
@ -303,15 +321,15 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
public PamBorderPane getClickTypeHolder() {
|
||||
return clickTypeHolder;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the table which holds a list of classifier
|
||||
* @return table which holds a list of classifiers
|
||||
*/
|
||||
public TableSettingsPane<ClickTypeProperty> getTablePane() {
|
||||
return this.settingsPane;
|
||||
return this.clickTypesTable;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get list of click classifiers
|
||||
* @return list of click classifiers
|
||||
@ -329,4 +347,48 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
return flipPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows a name alongside a graphic showing the current symbol.
|
||||
* @author Jamie Macaulay.
|
||||
*
|
||||
*/
|
||||
private class ClickTypeNameCell extends TableCell<ClickTypeProperty, String> {
|
||||
|
||||
/**
|
||||
* Symbol is drawn on the canvas
|
||||
*/
|
||||
Canvas canvas;
|
||||
|
||||
public static final double SYMBOL_SIZE = 20;
|
||||
|
||||
public ClickTypeNameCell() {
|
||||
super();
|
||||
canvas = new Canvas(SYMBOL_SIZE, SYMBOL_SIZE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
this.setText(item);
|
||||
|
||||
this.setGraphic(null);
|
||||
|
||||
if (this.getTableRow()!=null && this.getTableRow().getItem()!=null) {
|
||||
|
||||
SweepClassifierSet clickProperty = (SweepClassifierSet) this.getTableRow().getItem().getClickType();
|
||||
|
||||
if (clickProperty.symbol!=null) {
|
||||
canvas.getGraphicsContext2D().clearRect(0, 0, SYMBOL_SIZE, SYMBOL_SIZE);
|
||||
PamSymbolFX pamSymbolFX = new PamSymbolFX(clickProperty.symbol);
|
||||
pamSymbolFX.draw(canvas.getGraphicsContext2D(), new Point2D(SYMBOL_SIZE/2,SYMBOL_SIZE/2), SYMBOL_SIZE, SYMBOL_SIZE);
|
||||
this.setGraphic(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,16 @@
|
||||
package clickDetector.layoutFX.clickClassifiers;
|
||||
|
||||
|
||||
|
||||
import clickDetector.ClickControl;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifier;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierParameters;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
|
||||
import javafx.scene.text.FontPosture;
|
||||
import javafx.scene.text.FontWeight;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
/**
|
||||
* Slightly different pane for the sweep classifier.
|
||||
@ -38,12 +44,16 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
|
||||
@Override
|
||||
public void setClassifierPane(ClickTypeProperty clickTypeProperty){
|
||||
SweepClassifierSetPaneFX sweepPane=new SweepClassifierSetPaneFX(sweepClickClassifier);
|
||||
|
||||
|
||||
//set padding - want the flip pane not to have padding so back button reaches edge of node.
|
||||
((Region) sweepPane.getContentNode()).setPadding(new Insets(5,5,5,5));
|
||||
|
||||
//make it so the title of the pane is the same as the name as the classifier
|
||||
getFlipPane().getAdvLabel().textProperty().unbind();
|
||||
getFlipPane().getAdvLabel().textProperty().bind( sweepPane.getNameTextProperty());
|
||||
|
||||
getFlipPane().getAdvLabel().textProperty().bind(sweepPane.getNameTextProperty());
|
||||
getFlipPane().getPreAdvLabel().graphicProperty().bind(sweepPane.getNameGraphicProperty());
|
||||
|
||||
sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType());
|
||||
|
||||
sweepPane.setParams(clickTypeProperty);
|
||||
@ -54,6 +64,8 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
|
||||
getFlipPaneCloseButton().setOnAction((action)->{
|
||||
showFlipPane(false);
|
||||
sweepPane.getParams(clickTypeProperty);
|
||||
//need to refresh table to show symbol.
|
||||
clickTypesTable.getTableView().refresh();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@ package matchedTemplateClassifer
|
||||
;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import PamUtils.PamArrayUtils;
|
||||
import PamUtils.TxtFileUtils;
|
||||
@ -44,16 +46,21 @@ public class ImportTemplateCSV implements TemplateImport {
|
||||
//System.out.println("i: " + i + " : " + data.get(0).get(i));
|
||||
waveform[i]=data.get(0).get(i);
|
||||
}
|
||||
// System.out.println("String sR = " + data.get(1).get(0));
|
||||
|
||||
|
||||
//used big decimal here because String.,floatValue did not handle numbers like 3.85e05
|
||||
float sR = new BigDecimal(data.get(1).get(0)).floatValue();
|
||||
|
||||
float sR=data.get(1).get(0).floatValue();
|
||||
// float sR=data.get(1).get(0).floatValue();
|
||||
|
||||
//System.out.println("imported waveform");
|
||||
//PamArrayUtils.printArrayRaw(waveform);
|
||||
|
||||
|
||||
//now create waveform
|
||||
// System.out.println("Create a waveform with " + waveform.length + " samples with a sample rate of "
|
||||
// + sR + " Hz");
|
||||
System.out.println("Import a waveform with " + waveform.length + " samples with a sample rate of "
|
||||
+ sR + " Hz ");
|
||||
MatchTemplate matchedTemplate = new MatchTemplate(filePath.getName(), waveform, sR);
|
||||
//TODO
|
||||
return matchedTemplate;
|
||||
|
@ -129,7 +129,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
if (fft==null) fft=new FastFFT();
|
||||
|
||||
|
||||
//System.out.println("interpWaveform: " + waveformMatch.waveform.length + " sR " + waveformMatch.sR);
|
||||
// System.out.println("interpWaveform: " + waveformMatch.waveform.length + " sR " + waveformMatch.sR);
|
||||
|
||||
//re-sample the waveform if the sample rate is different
|
||||
this.interpWaveformMatch=interpWaveform(this.waveformMatch, sR);
|
||||
@ -145,7 +145,12 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
// System.out.println("MatchNorm: MATCH");
|
||||
// MTClassifierTest.normalizeTest(interpWaveformMatch);
|
||||
|
||||
waveformMatchFFT = fft.rfft(interpWaveformMatch, length);
|
||||
/**
|
||||
* There is an issue here because, if we have a long template waveform, then it
|
||||
* will become truncated and the actual waveform may be missed. This means we
|
||||
* have to use the peak of the template
|
||||
*/
|
||||
waveformMatchFFT = calcTemplateFFT(interpWaveformMatch, length);
|
||||
|
||||
//need to calculate the complex conjugate - note that originally I was flipping the array but this means
|
||||
//the max value does not equal one with identical waveforms...doh.
|
||||
@ -157,6 +162,42 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
return waveformMatchFFT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the FFT of an interpolate match template.
|
||||
* @param interpTemplateWaveform - the waveform interpolated to the correct sample rate.
|
||||
* @param length - the length of the FFT.
|
||||
* @return the FFT of the waveform as a complex array.
|
||||
*/
|
||||
private ComplexArray calcTemplateFFT(double[] interpTemplateWaveform, int length) {
|
||||
|
||||
ComplexArray fftTemplate;
|
||||
/**
|
||||
* There is an issue here because, if we have a long template waveform, then it
|
||||
* will become truncated and the actual waveform may be missed. This means we
|
||||
* have to use the peak of the template
|
||||
*/
|
||||
if (interpTemplateWaveform.length>length) {
|
||||
//If the template is long then need to find the peak, otherwise we will end up cross correlating with noise at the
|
||||
//start of the template.
|
||||
//because this is a template and not a random click we don't need to be so clever with how we find peaks. Find
|
||||
//the maximum and use around that.
|
||||
int pos = PamArrayUtils.maxPos(interpTemplateWaveform);
|
||||
|
||||
int startind = Math.max(0, pos-length/2);
|
||||
int endind = startind+length-1;
|
||||
|
||||
double[] peakTemplate = ArrayUtils.subarray(interpTemplateWaveform, startind, endind);
|
||||
fftTemplate = fft.rfft(peakTemplate, length);
|
||||
}
|
||||
else {
|
||||
//template waveform is padded by fft function
|
||||
fftTemplate = fft.rfft(interpTemplateWaveform, length);
|
||||
}
|
||||
|
||||
return fftTemplate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -181,13 +222,17 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
// this.inteprWaveformReject=PamArrayUtils.divide(inteprWaveformReject, PamArrayUtils.max(inteprWaveformReject));
|
||||
this.inteprWaveformReject = normaliseWaveform(inteprWaveformReject, this.normalisation);
|
||||
|
||||
|
||||
// System.out.println("MatchNorm: REJECT ");
|
||||
// MTClassifierTest.normalizeTest(inteprWaveformReject);
|
||||
// MTClassifierTest.printWaveform(inteprWaveformReject);
|
||||
|
||||
//System.out.println("waveformReject: " +inteprWaveformReject.length + " fftLength: " + getFFTLength(sR));
|
||||
waveformRejectFFT = fft.rfft(inteprWaveformReject, length);
|
||||
/**
|
||||
* There is an issue here because, if we have a long template waveform, then it
|
||||
* will become truncated and the actual waveform may be missed. This means we
|
||||
* have to use the peak of the template
|
||||
*/
|
||||
waveformRejectFFT = calcTemplateFFT(inteprWaveformReject, length);
|
||||
|
||||
|
||||
//need to calculate the complex conjugate - note that originally I was flipping the array but this means
|
||||
//the max value does not equal one with identical waveforms...doh.
|
||||
@ -293,7 +338,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
|
||||
ComplexArray matchTemplate = getWaveformMatchFFT(sR, matchResult.length());
|
||||
|
||||
//System.out.println("Match template length: " + matchTemplate.length() + "Click : " + click.length());
|
||||
// System.out.println("Match template length: " + matchTemplate.length() + "Click : " + click.length());
|
||||
|
||||
for (int i=0; i<matchTemplate.length(); i++) {
|
||||
matchResult.set(i, click.get(i).times(matchTemplate.get(i)));
|
||||
@ -376,7 +421,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
//set the stored sR
|
||||
currentSr=sR;
|
||||
|
||||
//System.out.println("Waveform click: len: " + click.length());
|
||||
System.out.println("Waveform click: len: " + click.length());
|
||||
|
||||
//System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject)+ " len " + interpWaveformMatch.length);
|
||||
|
||||
@ -396,9 +441,11 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
ComplexArray matchResult= new ComplexArray(fftLength);
|
||||
ComplexArray matchTemplate = getWaveformMatchFFT(sR,fftLength); //remember this is the complex conjugate
|
||||
|
||||
//System.out.println("matchTemplate interp: len: " + interpWaveformMatch.length+ " max: " + PamArrayUtils.max(interpWaveformMatch));
|
||||
//System.out.println("matchTemplate: len: " + waveformMatch.waveform.length+ " max: " + PamArrayUtils.max(waveformMatch.waveform));
|
||||
// System.out.println("matchTemplate interp: len: " + interpWaveformMatch.length+ " max: " + PamArrayUtils.max(interpWaveformMatch));
|
||||
// System.out.println("matchTemplate: len: " + waveformMatch.waveform.length+ " max: " + PamArrayUtils.max(waveformMatch.waveform));
|
||||
// System.out.println("matchTemplate interp: len: " + interpWaveformMatch.length+ " max: " + PamArrayUtils.max(interpWaveformMatch));
|
||||
|
||||
System.out.println("matchTemplate len: " + matchTemplate.length() + " click.length(): " +click.length());
|
||||
for (int i=0; i<Math.min(matchTemplate.length(), click.length()); i++) {
|
||||
matchResult.set(i, click.get(i).times(matchTemplate.get(i)));
|
||||
}
|
||||
@ -409,13 +456,10 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
rejectResult.set(i, click.get(i).times(rejectTemplate.get(i)));
|
||||
}
|
||||
|
||||
// System.out.println("Waveform Match max: " + PamArrayUtils.max(this.interpWaveformMatch));
|
||||
// System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject));
|
||||
System.out.println("Waveform Match max: " + PamArrayUtils.max(this.interpWaveformMatch));
|
||||
System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject));
|
||||
|
||||
//System.out.println("Click input: " + click.length() + " click template: " + matchTemplate.length());
|
||||
|
||||
|
||||
|
||||
|
||||
//must use scaling to get the same result as MATLAB
|
||||
if (fft==null) fft= new FastFFT();
|
||||
@ -453,17 +497,18 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
|
||||
// //TEST
|
||||
|
||||
//if set to "none" then reject template will return a NaN - TODO bit messy and inefficient.
|
||||
//if the reject template is set to "none" then reject template will return a NaN
|
||||
//TODO bit messy and inefficient.
|
||||
double result;
|
||||
double maxReject = PamArrayUtils.max(rejectReal);
|
||||
if (Double.isNaN(maxReject)) {
|
||||
// double maxReject = PamArrayUtils.max(rejectReal);
|
||||
if (Double.isNaN(maxreject)) {
|
||||
result = PamArrayUtils.max(matchReal);
|
||||
}
|
||||
else {
|
||||
result = PamArrayUtils.max(matchReal)-maxReject;
|
||||
result = PamArrayUtils.max(matchReal)-maxreject;
|
||||
}
|
||||
|
||||
//System.out.println("Match corr " + maxmatch + " Reject Corr: " + maxreject);
|
||||
System.out.println("Match corr " + maxmatch + " Reject Corr: " + maxreject);
|
||||
|
||||
MatchedTemplateResult matchTmpResult = new MatchedTemplateResult();
|
||||
matchTmpResult.threshold=result;
|
||||
@ -476,17 +521,19 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
|
||||
/**
|
||||
* Get the match waveform for the sample rate
|
||||
* @param sR - the sample rate in samples per second
|
||||
* @param waveformMatch - the template to interpolate or decimate.
|
||||
* @param sR - the target sample rate in samples per second
|
||||
*/
|
||||
private double[] interpWaveform(MatchTemplate waveformMatch, double sR) {
|
||||
//System.out.println("Interp waveform: " + " old: " + waveformMatch.sR + " new: " + sR);
|
||||
// System.out.println("Interp waveform: " + " old: " + waveformMatch.sR + " new: " + sR);
|
||||
|
||||
if ( waveformMatch.sR>sR) {
|
||||
if (waveformMatch.sR<sR) {
|
||||
//up sample
|
||||
double[] interpWaveformMatch=reSampleWaveform(waveformMatch.waveform, waveformMatch.sR, sR);
|
||||
return interpWaveformMatch;
|
||||
}
|
||||
else if (waveformMatch.sR<sR){
|
||||
else if (waveformMatch.sR>sR){
|
||||
//decimate
|
||||
// //TODO - make a better decimator?
|
||||
// double[] interpWaveformMatch=reSampleWaveform(waveformMatch.waveform, waveformMatch.sR, sR);
|
||||
// return interpWaveformMatch;
|
||||
@ -494,11 +541,9 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
return wavInterpolator.decimate(waveformMatch.waveform, waveformMatch.sR, (float) sR);
|
||||
}
|
||||
else {
|
||||
//nothing needed/
|
||||
//nothing needed
|
||||
return waveformMatch.waveform;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -529,7 +574,8 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
// // TODO Auto-generated method stub
|
||||
// return PamInterp.interpLinear(x, waveform, xi);
|
||||
|
||||
return PamInterp.interpWaveform(waveform, 1/binSize);
|
||||
// System.out.println("Interp waveform: " + binSize);
|
||||
return PamInterp.interpWaveform(waveform, 1./binSize);
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import java.util.Arrays;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.PamArrayUtils;
|
||||
import PamUtils.complex.ComplexArray;
|
||||
import PamView.symbol.PamSymbolManager;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
@ -288,6 +289,7 @@ public class MTProcess extends PamInstantProcess {
|
||||
@SuppressWarnings("unused")
|
||||
private double[] getWaveData(RawDataHolder clickDetection, int i) {
|
||||
double[] waveform;
|
||||
|
||||
if (this.getMTParams().peakSearch) {
|
||||
waveform = createRestrictedLenghtWave(clickDetection, i, lengthData[i],
|
||||
this.getMTParams().restrictedBins);
|
||||
@ -377,7 +379,14 @@ public class MTProcess extends PamInstantProcess {
|
||||
*/
|
||||
private double[] createRestrictedLenghtWave(RawDataHolder click, int chan, int[] lengthPoints,
|
||||
int restrictedBins) {
|
||||
return createRestrictedLenghtWave(click, chan, lengthPoints, restrictedBins, getWindow(restrictedBins));
|
||||
// System.out.println("Create restricted length wave: " + lengthPoints[0] + " to " + lengthPoints[1]);
|
||||
// System.out.println("Max before restrict: " + PamArrayUtils.max(click.getWaveData()[chan]));
|
||||
|
||||
double[] wave = createRestrictedLenghtWave(click, chan, lengthPoints, restrictedBins, getWindow(restrictedBins));
|
||||
|
||||
// System.out.println("Max after restrict: " + PamArrayUtils.max(click.getWaveData()[chan]));
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
||||
@ -412,7 +421,7 @@ public class MTProcess extends PamInstantProcess {
|
||||
|
||||
ArrayList<MatchedTemplateResult> results = new ArrayList<MatchedTemplateResult>();
|
||||
|
||||
//System.out.println("Click waveform max: " + PamArrayUtils.max(clickWaveform) + " sample rate: " + sR);
|
||||
System.out.println("Click waveform max: " + PamArrayUtils.max(clickWaveform) + " sample rate: " + sR);
|
||||
|
||||
//normalisation and picking peak has already been performed
|
||||
|
||||
|
@ -328,7 +328,7 @@ public class MTSettingsPane extends SettingsPane<MatchedTemplateParams> {
|
||||
private Node createClassifierPane(){
|
||||
|
||||
//with just one classifier.
|
||||
pamTabPane = new PamTabPane();
|
||||
pamTabPane = new PamTabPane();
|
||||
pamTabPane.setAddTabButton(true);
|
||||
// pamTabPane.getAddTabButton().setGraphic(PamGlyphDude.createPamGlyph(MaterialIcon.ADD, PamGuiManagerFX.iconSize));
|
||||
pamTabPane.getAddTabButton().setGraphic(PamGlyphDude.createPamIcon("mdi2p-plus", PamGuiManagerFX.iconSize));
|
||||
|
@ -40,19 +40,31 @@ public class MTClassifierOfflineTask extends OfflineTask<PamDataUnit<?,?>> {
|
||||
@Override
|
||||
public boolean processDataUnit(PamDataUnit dataUnit) {
|
||||
|
||||
count++;
|
||||
mtClassifierControl.getMTProcess().newClickData(dataUnit);
|
||||
try {
|
||||
// System.out.println("MT new data unit: " + dataUnit);
|
||||
|
||||
|
||||
count++;
|
||||
mtClassifierControl.getMTProcess().newClickData(dataUnit);
|
||||
|
||||
//since an annotation has been added might need to do this so that the data unit is actually saved.
|
||||
DataUnitFileInformation fileInfo = dataUnit.getDataUnitFileInformation();
|
||||
|
||||
// System.out.println("file info: " + fileInfo);
|
||||
if (fileInfo != null) {
|
||||
fileInfo.setNeedsUpdate(true);
|
||||
}
|
||||
dataUnit.updateDataUnit(System.currentTimeMillis());
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
//since an annotation has been added might need to do this so that the data unit is actually saved.
|
||||
DataUnitFileInformation fileInfo = dataUnit.getDataUnitFileInformation();
|
||||
|
||||
//System.out.println("file info: " + fileInfo);
|
||||
if (fileInfo != null) {
|
||||
fileInfo.setNeedsUpdate(true);
|
||||
}
|
||||
dataUnit.updateDataUnit(System.currentTimeMillis());
|
||||
|
||||
return true;
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,10 +96,12 @@ public class PamTabPane extends TabPane {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO - the button is removed and then added again it does not seem to appear....
|
||||
* Set whether a button shows to add tabs to the TabPane
|
||||
* @param addTabButton - true to show a button next to the last tab which allows new tabs to be added.
|
||||
*/
|
||||
public void setAddTabButton(boolean addTabButton) {
|
||||
if (this.addTabButton==addTabButton) return;
|
||||
this.addTabButton = addTabButton;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,26 @@
|
||||
package pamViewFX.fxNodes.flipPane;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Labeled;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.utilsFX.TextUtilsFX;
|
||||
|
||||
/**
|
||||
* Flip pane which has is supposed to be used for advanced settings. The front
|
||||
@ -32,15 +41,34 @@ public class PamFlipPane extends FlipPane {
|
||||
|
||||
private PamBorderPane frontPane;
|
||||
|
||||
private Label advLabel;
|
||||
|
||||
private PamButton backButton;
|
||||
|
||||
/**
|
||||
* Text field in the title of the advanced pane. This can be used to change settings.
|
||||
*/
|
||||
private TextField advLabel;
|
||||
|
||||
/**
|
||||
* Label which sits before the text field in the advanced settings pane title
|
||||
*/
|
||||
private Label preLabel;
|
||||
|
||||
/**
|
||||
* Label after the the text field in the advanced pane label - this can be set to say "settings" for example with the text field
|
||||
* then editable to change the name of a parameter.
|
||||
*/
|
||||
private Label postLabel;
|
||||
|
||||
|
||||
public PamFlipPane() {
|
||||
super();
|
||||
this.advPane = createAdvSettingsPane();
|
||||
this.getFront().getChildren().add(frontPane = new PamBorderPane());
|
||||
|
||||
// this.getFront().setStyle("-fx-background-color: grey;");
|
||||
// this.getBack().setStyle("-fx-background-color: grey;");
|
||||
|
||||
this.getBack().getChildren().add(advPane);
|
||||
this.setFlipTime(FLIP_TIME);
|
||||
|
||||
@ -77,6 +105,23 @@ public class PamFlipPane extends FlipPane {
|
||||
public PamBorderPane getAdvPane() {
|
||||
return advPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the advanced pane content.
|
||||
* @param - the content to set.
|
||||
*/
|
||||
public void setAdvPaneContent(Node content) {
|
||||
advPane.setCenter(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the front pane content.
|
||||
* @param - the content to set.
|
||||
*/
|
||||
public void setFrontContent(Node content) {
|
||||
frontPane.setCenter(content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -86,29 +131,70 @@ public class PamFlipPane extends FlipPane {
|
||||
|
||||
backButton = new PamButton();
|
||||
backButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-chevron-left", Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
// backButton.setStyle("-fx-background-color: -color-base-6");
|
||||
//backButton.setStyle("-fx-padding: 0,0,0,0");
|
||||
|
||||
backButton.setOnAction((action)->{
|
||||
// System.out.println("FLIP BACK TO FRONT");
|
||||
this.flipToFront();
|
||||
});
|
||||
|
||||
//make the back button blue so users can easily see the button.
|
||||
backButton.setStyle("-fx-background-radius: 0 5 5 0; -fx-border-radius: 0 5 5 0; -fx-background-color: -color-accent-6");
|
||||
|
||||
//backButton.setPrefWidth(150);
|
||||
|
||||
PamBorderPane advPane = new PamBorderPane();
|
||||
advPane.setPadding(new Insets(5,5,5,5));
|
||||
//advPane.setPadding(new Insets(5,5,5,5));
|
||||
|
||||
|
||||
// holds the title of the advanced pane. This consists of a label for a graphic,
|
||||
// an editable text field and a label after the editable settings field
|
||||
PamHBox titleHolder = new PamHBox();
|
||||
titleHolder.getChildren().addAll(preLabel = new Label(), advLabel = new TextField("Adv. "), postLabel = new Label("Settings"));
|
||||
preLabel.setId("label-title2");
|
||||
postLabel.setId("label-title2");
|
||||
titleHolder.setAlignment(Pos.CENTER);
|
||||
postLabel.setTextAlignment(TextAlignment.LEFT);
|
||||
postLabel.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
advLabel.setAlignment(Pos.CENTER);
|
||||
// advLabel.prefColumnCountProperty().bind(advLabel.textProperty().length().subtract(3));
|
||||
// Set Max and Min Width to PREF_SIZE so that the TextField is always PREF
|
||||
advLabel.setMinWidth(Region.USE_PREF_SIZE);
|
||||
advLabel.setMaxWidth(Region.USE_PREF_SIZE);
|
||||
|
||||
//pretty complicated to make sure the text field is the same size as the text that is being typed.
|
||||
advLabel.textProperty().addListener((ov, prevText, currText) -> {
|
||||
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
|
||||
Platform.runLater(() -> {
|
||||
Text text = new Text(currText);
|
||||
text.setFont(advLabel.getFont()); // Set the same font, so the size is the same
|
||||
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
|
||||
+ advLabel.getPadding().getLeft() + advLabel.getPadding().getRight() // Add the padding of the TextField
|
||||
+ 2d; // Add some spacing
|
||||
advLabel.setPrefWidth(width); // Set the width
|
||||
advLabel.positionCaret(advLabel.getCaretPosition()); // If you remove this line, it flashes a little bit
|
||||
});
|
||||
});
|
||||
advLabel.setId("label-title2");
|
||||
advLabel.setStyle("-fx-background-color: transparent");
|
||||
|
||||
titleHolder.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
|
||||
|
||||
//holds the back button and the title pane.
|
||||
PamHBox buttonHolder = new PamHBox();
|
||||
|
||||
buttonHolder.setBackground(null);
|
||||
//buttonHolder.setStyle("-fx-background-color: red;");
|
||||
buttonHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
buttonHolder.getChildren().addAll(backButton, advLabel = new Label("Adv. Settings"));
|
||||
buttonHolder.getChildren().addAll(backButton, titleHolder);
|
||||
|
||||
advLabel.setAlignment(Pos.CENTER);
|
||||
advLabel.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
|
||||
PamGuiManagerFX.titleFont2style(advLabel);
|
||||
|
||||
// PamGuiManagerFX.titleFont2style(advLabel);
|
||||
|
||||
|
||||
advLabel.setAlignment(Pos.CENTER);
|
||||
HBox.setHgrow(advLabel, Priority.ALWAYS);
|
||||
HBox.setHgrow(titleHolder, Priority.ALWAYS);
|
||||
|
||||
advPane.setTop(buttonHolder);
|
||||
|
||||
@ -117,16 +203,45 @@ public class PamFlipPane extends FlipPane {
|
||||
}
|
||||
|
||||
|
||||
public Label getAdvLabel() {
|
||||
public TextField getAdvLabel() {
|
||||
return advLabel;
|
||||
}
|
||||
|
||||
public void setAdvLabel(Label advLabel) {
|
||||
this.advLabel = advLabel;
|
||||
}
|
||||
// public void setAdvLabel(Label advLabel) {
|
||||
// this.advLabel = advLabel;
|
||||
// }
|
||||
|
||||
public PamButton getBackButton() {
|
||||
return backButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label located before the editable label in the title
|
||||
* @return the label before the editable label
|
||||
*/
|
||||
public Label getPreAdvLabel() {
|
||||
return preLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label located after the editable label in the title
|
||||
* @return the label after the editable label
|
||||
*/
|
||||
public Label getPostAdvLabel() {
|
||||
return postLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the flip pane is showing the front.
|
||||
*/
|
||||
public boolean isShowingFront() {
|
||||
return super.flipFrontProperty().get();
|
||||
}
|
||||
|
||||
public void setAdvLabelEditable(boolean b) {
|
||||
this.advLabel.setEditable(b);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
|
||||
}
|
||||
else {
|
||||
mainPane.setTop(createFilterPane());
|
||||
mainPane.setBottom(createBodeGraph());
|
||||
mainPane.setCenter(createBodeGraph());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,24 @@
|
||||
package pamViewFX.fxNodes.utilityPanes;
|
||||
|
||||
import org.controlsfx.control.SegmentedButton;
|
||||
|
||||
import PamController.SettingsPane;
|
||||
import PamUtils.LatLong;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import javafx.scene.control.Toggle;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
|
||||
/**
|
||||
* Pane with controls to to set the values for a Latitude and Longitude. The pane allows users to
|
||||
* change the Latitude and Longitude in both Degrees, Decimal minutes and Degrees, Minutes, Seconds
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
@ -27,37 +32,62 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
/**
|
||||
* The radio button to select decimal minutes
|
||||
*/
|
||||
private RadioButton decimalMinutes;
|
||||
private ToggleButton decimalMinutes;
|
||||
|
||||
/**
|
||||
* Radio button to input minutes and seconds.
|
||||
*/
|
||||
private RadioButton minutesSeconds;
|
||||
private ToggleButton minutesSeconds;
|
||||
|
||||
/**
|
||||
* Lat long strip
|
||||
*/
|
||||
private LatLongStrip latStrip, longStrip;
|
||||
|
||||
private PamBorderPane mainPane;
|
||||
private PamVBox mainPane;
|
||||
|
||||
private ToggleButton decimal;
|
||||
|
||||
/**
|
||||
* Segmented button that also selection of the latitude and longitude format type.
|
||||
*/
|
||||
private SegmentedButton segmentedButton;
|
||||
|
||||
|
||||
public LatLongPane(String title) {
|
||||
super(null);
|
||||
|
||||
|
||||
mainPane = new PamVBox();
|
||||
mainPane.setSpacing(5);
|
||||
mainPane.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
Label titleLabel = new Label(title);
|
||||
titleLabel.maxWidth(Double.MAX_VALUE);
|
||||
titleLabel.setTextAlignment(TextAlignment.LEFT);
|
||||
PamGuiManagerFX.titleFont2style(titleLabel);
|
||||
mainPane.getChildren().add(titleLabel);
|
||||
|
||||
|
||||
latLong= new LatLong();
|
||||
|
||||
mainPane = new PamBorderPane();
|
||||
|
||||
decimalMinutes = new ToggleButton("Degrees, Decimal minutes");
|
||||
minutesSeconds = new ToggleButton("Degrees, Minutes, Seconds");
|
||||
decimal = new ToggleButton("Decimal");
|
||||
|
||||
segmentedButton = new SegmentedButton();
|
||||
segmentedButton.getButtons().addAll(decimalMinutes, minutesSeconds, decimal);
|
||||
|
||||
PamHBox top = new PamHBox();
|
||||
top.setSpacing(5);
|
||||
top.getChildren().add(new Label("Unit type :"));
|
||||
top.getChildren().add(decimalMinutes = new RadioButton("Degrees, Decimal minutes"));
|
||||
top.getChildren().add(minutesSeconds = new RadioButton("Degrees, Minutes, Seconds"));
|
||||
top.getChildren().add(segmentedButton);
|
||||
|
||||
ToggleGroup bg = new ToggleGroup();
|
||||
decimalMinutes.setToggleGroup(bg);
|
||||
minutesSeconds.setToggleGroup(bg);
|
||||
// ToggleGroup bg = new ToggleGroup();
|
||||
// decimalMinutes.setToggleGroup(bg);
|
||||
// minutesSeconds.setToggleGroup(bg);
|
||||
// decimal.setToggleGroup(bg);
|
||||
|
||||
decimalMinutes.setOnAction((action)->{
|
||||
actionPerformed(action);
|
||||
@ -66,7 +96,12 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
minutesSeconds.setOnAction((action)->{
|
||||
actionPerformed(action);
|
||||
});
|
||||
mainPane.setTop(top);
|
||||
|
||||
decimal.setOnAction((action)->{
|
||||
actionPerformed(action);
|
||||
});
|
||||
|
||||
mainPane.getChildren().add(top);
|
||||
|
||||
PamVBox cent = new PamVBox();
|
||||
cent.setSpacing(5);
|
||||
@ -75,8 +110,12 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
cent.getChildren().add(latStrip = new LatLongStrip(true));
|
||||
cent.getChildren().add(longStrip = new LatLongStrip(false));
|
||||
|
||||
mainPane.setCenter(cent);
|
||||
//bit of a hack that makes sure controls are aligned for the latitude and longitude.
|
||||
latStrip.getTitleLabel().prefWidthProperty().bind(longStrip.getTitleLabel().widthProperty());
|
||||
|
||||
mainPane.getChildren().add(cent);
|
||||
|
||||
decimal.setSelected(true);
|
||||
}
|
||||
|
||||
|
||||
@ -85,16 +124,17 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
*/
|
||||
public void actionPerformed(javafx.event.ActionEvent action) {
|
||||
|
||||
|
||||
if (action.getSource() == decimalMinutes) {
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_DECIMALMINUTES);
|
||||
// if (latStrip != null) {
|
||||
// latStrip.setDecimalMinutes(true);
|
||||
// longStrip.setDecimalMinutes(true);
|
||||
// }
|
||||
// if (latStrip != null) {
|
||||
// latStrip.setDecimalMinutes(true);
|
||||
// longStrip.setDecimalMinutes(true);
|
||||
// }
|
||||
latStrip.showControls(LatLong.FORMAT_DECIMALMINUTES);
|
||||
longStrip.showControls(LatLong.FORMAT_DECIMALMINUTES);
|
||||
}
|
||||
else if (action.getSource() == minutesSeconds) {
|
||||
else if (action.getSource() == minutesSeconds){
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_MINUTESSECONDS);
|
||||
// if (latStrip != null) {
|
||||
// latStrip.setDecimalMinutes(false);
|
||||
@ -105,19 +145,26 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
latStrip.showControls(LatLong.FORMAT_MINUTESSECONDS);
|
||||
longStrip.showControls(LatLong.FORMAT_MINUTESSECONDS);
|
||||
}
|
||||
|
||||
else if (action.getSource() == decimal){
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_DECIMAL);
|
||||
latStrip.showControls(LatLong.FORMAT_DECIMAL);
|
||||
longStrip.showControls(LatLong.FORMAT_DECIMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void showLatLong() {
|
||||
decimalMinutes.setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_DECIMALMINUTES);
|
||||
minutesSeconds.setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_MINUTESSECONDS);
|
||||
latStrip.showControls(LatLong.getFormatStyle() );
|
||||
longStrip.showControls(LatLong.getFormatStyle() );
|
||||
latStrip.sayValue(latLong.getLatitude());
|
||||
longStrip.sayValue(latLong.getLongitude());
|
||||
|
||||
decimalMinutes .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_DECIMALMINUTES);
|
||||
minutesSeconds .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_MINUTESSECONDS);
|
||||
decimal .setSelected(LatLong.getFormatStyle() == LatLong.FORMAT_DECIMAL);
|
||||
|
||||
latStrip .showControls(LatLong.getFormatStyle() );
|
||||
longStrip .showControls(LatLong.getFormatStyle() );
|
||||
latStrip .setValue(latLong.getLatitude());
|
||||
longStrip .setValue(latLong.getLongitude());
|
||||
}
|
||||
|
||||
|
||||
@ -127,6 +174,21 @@ public class LatLongPane extends SettingsPane<LatLong>{
|
||||
*/
|
||||
@Override
|
||||
public LatLong getParams(LatLong currentParams) {
|
||||
|
||||
Toggle selectedButton = this.segmentedButton.getToggleGroup().getSelectedToggle();
|
||||
|
||||
if (selectedButton == decimalMinutes) {
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_DECIMALMINUTES);
|
||||
|
||||
}
|
||||
else if (selectedButton == minutesSeconds){
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_MINUTESSECONDS);
|
||||
|
||||
}
|
||||
else if (selectedButton == decimal){
|
||||
LatLong.setFormatStyle(LatLong.FORMAT_DECIMAL);
|
||||
}
|
||||
|
||||
latLong = new LatLong(latStrip.getValue(), longStrip.getValue());
|
||||
if (Double.isNaN(latLong.getLatitude()) || Double.isNaN(latLong.getLongitude())) {
|
||||
return null;
|
||||
|
@ -17,24 +17,30 @@ import pamViewFX.fxNodes.PamHBox;
|
||||
*
|
||||
*/
|
||||
public class LatLongStrip extends PamBorderPane {
|
||||
|
||||
|
||||
Label formattedText;
|
||||
TextField degrees, minutes, seconds, decminutes;
|
||||
Label dl, ml, sl, dml;
|
||||
TextField degrees, minutes, seconds, decminutes, decimal;
|
||||
Label dl, ml, sl, dml, dec;
|
||||
ComboBox<String> nsew;
|
||||
boolean isLatitude;
|
||||
// boolean decimalMinutes = true;
|
||||
|
||||
// boolean decimalMinutes = true;
|
||||
|
||||
/**
|
||||
* HBox to hold decimal minutes, degrees, seconds controls.
|
||||
*/
|
||||
private PamHBox degHBox;
|
||||
|
||||
|
||||
/**
|
||||
* HBox to hold decimal controls
|
||||
*/
|
||||
private PamHBox decHBox;
|
||||
|
||||
|
||||
/**
|
||||
* The format type e.g. LatLong.FORMAT_DECIMALMINUTES.
|
||||
*/
|
||||
private int formatType = LatLong.FORMAT_DECIMALMINUTES;
|
||||
private Label titleLabel;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a strip of controls to include in a larger dialog.
|
||||
@ -48,7 +54,7 @@ public class LatLongStrip extends PamBorderPane {
|
||||
isLatitude = latitude;
|
||||
createDialogStrip(showBorder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a strip of controls to include in a larger dialog.
|
||||
* <p>By default the strip will have a titled border with the
|
||||
@ -59,27 +65,33 @@ public class LatLongStrip extends PamBorderPane {
|
||||
isLatitude = latitude;
|
||||
createDialogStrip(true);
|
||||
}
|
||||
|
||||
|
||||
private void createDialogStrip(boolean showBorder) {
|
||||
|
||||
String borderTitle;
|
||||
if (isLatitude) borderTitle = "Latitude";
|
||||
else borderTitle = "Longitude";
|
||||
|
||||
Label title= new Label(borderTitle);
|
||||
PamGuiManagerFX.titleFont2style(title);
|
||||
// title.setFont(PamGuiManagerFX.titleFontSize2);
|
||||
|
||||
String title;
|
||||
if (isLatitude) title = "Latitude";
|
||||
else title = "Longitude";
|
||||
|
||||
// title.setFont(PamGuiManagerFX.titleFontSize2);
|
||||
|
||||
degrees = new TextField();
|
||||
degrees.setEditable(true);
|
||||
degrees.setPrefColumnCount(4);
|
||||
minutes = new TextField();
|
||||
minutes.setPrefColumnCount(3);
|
||||
minutes.setEditable(true);
|
||||
|
||||
seconds = new TextField();
|
||||
seconds.setPrefColumnCount(6);
|
||||
seconds.setEditable(true);
|
||||
decminutes = new TextField();
|
||||
decminutes.setPrefColumnCount(6);
|
||||
|
||||
decminutes.setEditable(true);
|
||||
|
||||
decimal=new TextField();
|
||||
decimal.setPrefColumnCount(9);
|
||||
decimal.setEditable(true);
|
||||
|
||||
nsew = new ComboBox<String>();
|
||||
nsew.setOnAction((action)->{
|
||||
double v = getValue();
|
||||
@ -91,6 +103,8 @@ public class LatLongStrip extends PamBorderPane {
|
||||
ml = new Label("min.");
|
||||
sl = new Label("sec.");
|
||||
dml = new Label("dec min.");
|
||||
dec = new Label("decimal deg.");
|
||||
|
||||
formattedText = new Label("Position");
|
||||
if (isLatitude) {
|
||||
nsew.getItems().add("N");
|
||||
@ -100,123 +114,192 @@ public class LatLongStrip extends PamBorderPane {
|
||||
nsew.getItems().add("E");
|
||||
nsew.getItems().add("W");
|
||||
}
|
||||
|
||||
|
||||
degrees.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
|
||||
minutes.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
|
||||
seconds.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
|
||||
decminutes.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
|
||||
decimal.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
nsew.setOnKeyPressed((key)->{
|
||||
newTypedValues(key);
|
||||
});
|
||||
|
||||
|
||||
|
||||
degHBox = new PamHBox();
|
||||
degHBox.setSpacing(5);
|
||||
degHBox.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
this.setRight(nsew);
|
||||
this.setCenter(degHBox);
|
||||
|
||||
PamHBox holder= new PamHBox();
|
||||
holder.setAlignment(Pos.CENTER_LEFT);
|
||||
holder.setSpacing(5);
|
||||
holder.getChildren().addAll(titleLabel = new Label(title), degHBox, nsew);
|
||||
|
||||
this.setCenter(holder);
|
||||
this.setBottom(formattedText);
|
||||
|
||||
showControls( LatLong.FORMAT_DECIMALMINUTES);
|
||||
showControls(formatType);
|
||||
}
|
||||
|
||||
private void newTypedValues(KeyEvent e) {
|
||||
double v = getValue();
|
||||
// now need to put that into the fields that
|
||||
// are not currently shown so that they are
|
||||
// ready if needed.
|
||||
|
||||
if (e != null) {
|
||||
sayValue(v, true);
|
||||
}
|
||||
|
||||
// // now need to put that into the fields that
|
||||
// // are not currently shown so that they are
|
||||
// // ready if needed.
|
||||
//
|
||||
// if (e != null) {
|
||||
// setValue(v, true);
|
||||
// }
|
||||
|
||||
// and say the formated version
|
||||
sayFormattedValue(v);
|
||||
}
|
||||
|
||||
|
||||
public void showControls(int formatStyle) {
|
||||
boolean decimal = (formatStyle == LatLong.FORMAT_DECIMALMINUTES);
|
||||
|
||||
if (formatType==formatStyle) {
|
||||
return;
|
||||
}
|
||||
|
||||
//important this comes before setting format style.
|
||||
double currentValue = getValue();
|
||||
|
||||
this.formatType = formatStyle;
|
||||
|
||||
degHBox.getChildren().clear();
|
||||
if (decimal) {
|
||||
|
||||
System.out.println("FORMATSTYLE: " + formatStyle + " val " + currentValue);
|
||||
|
||||
switch (formatType) {
|
||||
case LatLong.FORMAT_DECIMALMINUTES:
|
||||
degHBox.getChildren().add(dl);
|
||||
degHBox.getChildren().add(degrees);
|
||||
degHBox.getChildren().add(dml);
|
||||
degHBox.getChildren().add(decminutes);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
case LatLong.FORMAT_MINUTESSECONDS:
|
||||
degHBox.getChildren().add(dl);
|
||||
degHBox.getChildren().add(degrees);
|
||||
degHBox.getChildren().add(ml);
|
||||
degHBox.getChildren().add(minutes);
|
||||
degHBox.getChildren().add(sl);
|
||||
degHBox.getChildren().add(seconds);
|
||||
break;
|
||||
case LatLong.FORMAT_DECIMAL:
|
||||
degHBox.getChildren().add(dec);
|
||||
degHBox.getChildren().add(decimal);
|
||||
break;
|
||||
|
||||
}
|
||||
minutes.setVisible(decimal == false);
|
||||
ml.setVisible(decimal == false);
|
||||
seconds.setVisible(decimal == false);
|
||||
sl.setVisible(decimal == false);
|
||||
decminutes.setVisible(decimal);
|
||||
dml.setVisible(decimal);
|
||||
|
||||
setValue(currentValue);
|
||||
|
||||
sayFormattedValue(getValue());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set data in the lat long dialog strip
|
||||
* @param value Lat or Long in decimal degrees.
|
||||
*/
|
||||
public void sayValue(double value) {
|
||||
sayValue(value, false);
|
||||
public void setValue(double value) {
|
||||
setValue(value, false);
|
||||
}
|
||||
|
||||
public void sayValue(double value, boolean hiddenOnly) {
|
||||
|
||||
public void setValue(double value, boolean hiddenOnly) {
|
||||
|
||||
System.out.println("Set value: " + value);
|
||||
if (value >= 0) {
|
||||
nsew.getSelectionModel().select(0);
|
||||
}
|
||||
else {
|
||||
nsew.getSelectionModel().select(1);
|
||||
}
|
||||
|
||||
|
||||
double deg = LatLong.getSignedDegrees(value);
|
||||
// System.out.println("Deg: " + LatLong.getSignedDegrees(value) + " value: " +value);
|
||||
|
||||
if (degrees.isVisible() == false || !hiddenOnly) degrees.setText(String.format("%d", (int)Math.abs(deg)));
|
||||
if (minutes.isVisible() == false || !hiddenOnly) minutes.setText(String.format("%d", LatLong.getIntegerMinutes(value)));
|
||||
if (decminutes.isVisible() == false || !hiddenOnly) decminutes.setText(String.format("%3.5f", LatLong.getDecimalMinutes(value)));
|
||||
if (seconds.isVisible() == false || !hiddenOnly) seconds.setText(String.format("%3.5f", LatLong.getSeconds(value)));
|
||||
if (nsew.isVisible() == false || !hiddenOnly) nsew.getSelectionModel().select(deg >= 0 ? 0 : 1);
|
||||
// System.out.println("Deg: " + LatLong.getSignedDegrees(value) + " value: " +value);
|
||||
|
||||
|
||||
// if (degrees.isVisible() == false || !hiddenOnly) degrees.setText(String.format("%d", (int)Math.abs(deg)));
|
||||
// if (minutes.isVisible() == false || !hiddenOnly) minutes.setText(String.format("%d", LatLong.getIntegerMinutes(value)));
|
||||
// if (decminutes.isVisible() == false || !hiddenOnly) decminutes.setText(String.format("%3.5f", LatLong.getDecimalMinutes(value)));
|
||||
// if (seconds.isVisible() == false || !hiddenOnly) seconds.setText(String.format("%3.5f", LatLong.getSeconds(value)));
|
||||
// if (nsew.isVisible() == false || !hiddenOnly) nsew.getSelectionModel().select(deg >= 0 ? 0 : 1);
|
||||
// if (decimal.isVisible() == false || !hiddenOnly) decimal.setText(String.format("%.8f", value));
|
||||
|
||||
switch (formatType) {
|
||||
case LatLong.FORMAT_DECIMALMINUTES:
|
||||
|
||||
degrees.setText(String.format("%d", (int)Math.abs(deg)));
|
||||
decminutes.setText(String.format("%3.5f", LatLong.getDecimalMinutes(value)));
|
||||
|
||||
break;
|
||||
case LatLong.FORMAT_MINUTESSECONDS:
|
||||
|
||||
degrees.setText(String.format("%d", (int)Math.abs(deg)));
|
||||
minutes.setText(String.format("%d", LatLong.getIntegerMinutes(value)));
|
||||
seconds.setText(String.format("%3.5f", LatLong.getSeconds(value)));
|
||||
|
||||
break;
|
||||
case LatLong.FORMAT_DECIMAL:
|
||||
|
||||
decimal.setText(String.format("%.8f", value));
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
sayFormattedValue(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value for the latitude and longitude
|
||||
* @return the value.
|
||||
* Get the value for the latitude or longitude in decimal
|
||||
* @return the value - the value in decimal
|
||||
*/
|
||||
public double getValue() {
|
||||
|
||||
double deg = 0;
|
||||
double min = 0;
|
||||
double sec = 0;
|
||||
double sin = 1.;
|
||||
if (nsew.getSelectionModel().getSelectedIndex()== 1) sin = -1.;
|
||||
|
||||
if (nsew.getSelectionModel().getSelectedIndex() == 1) sin = -1.;
|
||||
|
||||
|
||||
if (formatType == LatLong.FORMAT_DECIMAL){
|
||||
try {
|
||||
deg = Double.valueOf(decimal.getText());
|
||||
return deg;
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
deg = Integer.valueOf(degrees.getText());
|
||||
deg = Integer.valueOf(degrees.getText());
|
||||
}
|
||||
catch (NumberFormatException Ex) {
|
||||
return Double.NaN;
|
||||
}
|
||||
if (LatLong.getFormatStyle() == LatLong.FORMAT_DECIMALMINUTES){
|
||||
|
||||
|
||||
if (formatType == LatLong.FORMAT_DECIMALMINUTES){
|
||||
try {
|
||||
min = Double.valueOf(decminutes.getText());
|
||||
}
|
||||
@ -237,12 +320,13 @@ public class LatLongStrip extends PamBorderPane {
|
||||
catch (NumberFormatException ex) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
}
|
||||
deg += min/60 + sec/3600;
|
||||
deg *= sin;
|
||||
return deg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear the latitude/longitude data from the pane.
|
||||
*/
|
||||
@ -251,9 +335,10 @@ public class LatLongStrip extends PamBorderPane {
|
||||
minutes.setText("");
|
||||
seconds.setText("");
|
||||
decminutes.setText("");
|
||||
decimal.setText("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void sayFormattedValue(double value) {
|
||||
if (isLatitude) {
|
||||
formattedText.setText(LatLong.formatLatitude(value));
|
||||
@ -262,13 +347,13 @@ public class LatLongStrip extends PamBorderPane {
|
||||
formattedText.setText(LatLong.formatLongitude(value));
|
||||
}
|
||||
}
|
||||
// public boolean isDecimalMinutes() {
|
||||
// return decimalMinutes;
|
||||
// }
|
||||
// public void setDecimalMinutes(boolean decimalMinutes) {
|
||||
// this.decimalMinutes = decimalMinutes;
|
||||
// showControls();
|
||||
// }
|
||||
// public boolean isDecimalMinutes() {
|
||||
// return decimalMinutes;
|
||||
// }
|
||||
// public void setDecimalMinutes(boolean decimalMinutes) {
|
||||
// this.decimalMinutes = decimalMinutes;
|
||||
// showControls();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Set the pane to be enabled or disabled.
|
||||
@ -281,5 +366,16 @@ public class LatLongStrip extends PamBorderPane {
|
||||
seconds.setDisable(!enabled);
|
||||
decminutes.setDisable(!enabled);
|
||||
nsew.setDisable(!enabled);
|
||||
decimal.setDisable(!enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title label.
|
||||
* @return the title label.
|
||||
*/
|
||||
public Label getTitleLabel() {
|
||||
return titleLabel;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
40
src/pamViewFX/fxNodes/utilsFX/TextUtilsFX.java
Normal file
40
src/pamViewFX/fxNodes/utilsFX/TextUtilsFX.java
Normal file
@ -0,0 +1,40 @@
|
||||
package pamViewFX.fxNodes.utilsFX;
|
||||
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.text.TextBoundsType;
|
||||
|
||||
public class TextUtilsFX {
|
||||
|
||||
static final Text helper;
|
||||
static final double DEFAULT_WRAPPING_WIDTH;
|
||||
static final double DEFAULT_LINE_SPACING;
|
||||
static final String DEFAULT_TEXT;
|
||||
static final TextBoundsType DEFAULT_BOUNDS_TYPE;
|
||||
static {
|
||||
helper = new Text();
|
||||
DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
|
||||
DEFAULT_LINE_SPACING = helper.getLineSpacing();
|
||||
DEFAULT_TEXT = helper.getText();
|
||||
DEFAULT_BOUNDS_TYPE = helper.getBoundsType();
|
||||
}
|
||||
|
||||
public static double computeTextWidth(Font font, String text, double help0) {
|
||||
// Toolkit.getToolkit().getFontLoader().computeStringWidth(field.getText(),
|
||||
// field.getFont());
|
||||
|
||||
helper.setText(text);
|
||||
helper.setFont(font);
|
||||
|
||||
helper.setWrappingWidth(0.0D);
|
||||
helper.setLineSpacing(0.0D);
|
||||
double d = Math.min(helper.prefWidth(-1.0D), help0);
|
||||
helper.setWrappingWidth((int) Math.ceil(d));
|
||||
d = Math.ceil(helper.getLayoutBounds().getWidth());
|
||||
|
||||
helper.setWrappingWidth(DEFAULT_WRAPPING_WIDTH);
|
||||
helper.setLineSpacing(DEFAULT_LINE_SPACING);
|
||||
helper.setText(DEFAULT_TEXT);
|
||||
return d;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user