mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-25 08:32:32 +00:00
Merge remote-tracking branch 'origin/main' into Tethys
This commit is contained in:
commit
3cf0a4e1e6
@ -8,7 +8,6 @@
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
|
@ -22,19 +22,19 @@ public class PamArrayUtils {
|
||||
/**
|
||||
* Calculate the mean of one dimension within a list of points. <i>e.g.</i> the points might be a list of [x y z] co-ordinates in
|
||||
* which case the dim=0 would return the mean of all x points.
|
||||
* @param array - a list of points
|
||||
* @param successJump - a list of points
|
||||
* @param InitialtoIgnorePercentage: ignore the first percentage of results
|
||||
* @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<double[]> successJump, double InitialtoIgnorePercentage, int dim){
|
||||
|
||||
double meanTotal=0;
|
||||
int n=0;
|
||||
int forStart=(int) Math.round((InitialtoIgnorePercentage)*array.size());
|
||||
int forStart=(int) Math.round((InitialtoIgnorePercentage)*successJump.size());
|
||||
|
||||
for (int i=forStart; i<array.size();i++){
|
||||
meanTotal+= array.get(i)[dim];
|
||||
for (int i=forStart; i<successJump.size();i++){
|
||||
meanTotal+= successJump.get(i)[dim];
|
||||
n++;
|
||||
}
|
||||
|
||||
@ -42,24 +42,25 @@ public class PamArrayUtils {
|
||||
double mean=meanTotal/n;
|
||||
return mean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the standard deviation of an array of doubles, ignoring an 'initialtoIgnorePercentage' percentage of jumps
|
||||
* @param array
|
||||
* @param successJump
|
||||
* @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<double[]> successJump, double initialtoIgnorePercentage, int dim){
|
||||
double std=0.0;
|
||||
|
||||
int n=0;
|
||||
int forStart=(int) Math.round((initialtoIgnorePercentage)*array.size());
|
||||
int forStart=(int) Math.round((initialtoIgnorePercentage)*successJump.size());
|
||||
|
||||
double meanTotal= mean(array, initialtoIgnorePercentage, dim);
|
||||
double meanTotal= mean(successJump, initialtoIgnorePercentage, dim);
|
||||
|
||||
//calculate standard deviation
|
||||
for (int k=forStart;k<array.size(); k++){
|
||||
std+=Math.pow((array.get(k)[dim]-meanTotal),2);
|
||||
for (int k=forStart;k<successJump.size(); k++){
|
||||
std+=Math.pow((successJump.get(k)[dim]-meanTotal),2);
|
||||
}
|
||||
|
||||
//standard deviation
|
||||
@ -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,152 @@ 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,17 @@ 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());
|
||||
// removed DG 2023 12 14 since not everything was in this merge that was required Needs to be put back.
|
||||
// getFlipPane().getPreAdvLabel().graphicProperty().bind(sweepPane.getNameGraphicProperty());
|
||||
|
||||
sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType());
|
||||
|
||||
sweepPane.setParams(clickTypeProperty);
|
||||
@ -54,6 +65,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;
|
||||
|
@ -130,7 +130,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);
|
||||
@ -146,7 +146,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.
|
||||
@ -158,6 +163,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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -182,13 +223,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.
|
||||
@ -294,7 +339,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)));
|
||||
@ -377,7 +422,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);
|
||||
|
||||
@ -397,9 +442,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)));
|
||||
}
|
||||
@ -410,13 +457,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();
|
||||
@ -454,17 +498,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;
|
||||
@ -477,17 +522,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;
|
||||
@ -495,11 +542,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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -530,7 +575,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