diff --git a/.classpath b/.classpath index ba93b2e0..188c7291 100644 --- a/.classpath +++ b/.classpath @@ -6,9 +6,8 @@ - + - diff --git a/src/Array/layoutFX/InterpChoicePane.java b/src/Array/layoutFX/InterpChoicePane.java index 590efc5d..b44b534b 100644 --- a/src/Array/layoutFX/InterpChoicePane.java +++ b/src/Array/layoutFX/InterpChoicePane.java @@ -23,7 +23,7 @@ public class InterpChoicePane extends InterpSettingsPane { interpChoiceBox = new ChoiceBox(); interpChoiceBox.getItems().addAll(interpChoice); - + interpChoiceBox.setMaxWidth(Double.MAX_VALUE); interpChoiceBox.setConverter(new StringConverter<>() { @Override diff --git a/src/Array/layoutFX/StreamerSettingsPane.java b/src/Array/layoutFX/StreamerSettingsPane.java index b1663434..1107990a 100644 --- a/src/Array/layoutFX/StreamerSettingsPane.java +++ b/src/Array/layoutFX/StreamerSettingsPane.java @@ -490,14 +490,14 @@ public class StreamerSettingsPane extends SettingsPane { defaultStreamer.setDz(Double.valueOf(zPosErr.getText())); } catch (NumberFormatException e) { - System.err.println("There is a problem with one of the position parameters in the streamer panel"); + 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("There is a problem with the interpolation selection streamer panel"); + System.err.println("Streamer getParams: There is an index problem with the interpolation selection streamer panel: index = " + im); } currentArray.setOriginInterpolation(im); // try { @@ -516,7 +516,7 @@ public class StreamerSettingsPane extends SettingsPane { // } // masterLocator.setHydrophoneLocator(streamerIndex, locator); if (currentOriginMethod == null) { - System.err.println("No hydrophoneorigin method selected in streamer panel"); + System.err.println("Streamer getParams: No hydrophoneorigin method selected in streamer panel"); } OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent(); if (mthDialogComponent != null) { @@ -532,13 +532,13 @@ public class StreamerSettingsPane extends SettingsPane { defaultStreamer.setRoll(getDoubleValue(roll)); // } if (!heading.isDisable() && defaultStreamer.getHeading() == null) { - System.err.println("You must enter a fixed value for the streamer heading"); + System.err.println("Streamer getParams: You must enter a fixed value for the streamer heading"); } if (!pitch.isDisable() && defaultStreamer.getPitch() == null) { - System.err.println("You must enter a fixed value for the streamer pitch"); + System.err.println("Streamer getParams: You must enter a fixed value for the streamer pitch"); } if (!roll.isDisable() && defaultStreamer.getRoll() == null) { - System.err.println("You must enter a fixed value for the streamer roll"); + System.err.println("Streamer getParams: You must enter a fixed value for the streamer roll"); } @@ -563,13 +563,13 @@ public class StreamerSettingsPane extends SettingsPane { } } - return currParams; + return defaultStreamer; } @Override public void setParams(Streamer input) { if (input==null) { - System.out.print("The input streamer is null"); + System.out.print("Streamer setParams: The input streamer is null"); } this.defaultStreamer=input; // origin methods @@ -616,21 +616,24 @@ public class StreamerSettingsPane extends SettingsPane { OriginDialogComponent mthDialogComponent = mth.getDialogComponent(); if (mthDialogComponent != null) { + System.out.println("Streamer setParams: Set origin component: "); mthDialogComponent.setParams(); } - System.out.println("Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll()); + 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("Origin interpolator: " + currentArray.getOriginInterpolation()); + System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation()); if (currentArray.getOriginInterpolation()<0) { interpPane.setSelection(0); } - else interpPane.setSelection(currentArray.getOriginInterpolation()); + else { + interpPane.setSelection(currentArray.getOriginInterpolation()); + } ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values(); for (int i = 0; i < sensorFields.length; i++) { diff --git a/src/Array/layoutFX/StreamersPane.java b/src/Array/layoutFX/StreamersPane.java index 5719892e..c921df8b 100644 --- a/src/Array/layoutFX/StreamersPane.java +++ b/src/Array/layoutFX/StreamersPane.java @@ -55,7 +55,7 @@ public class StreamersPane extends PamBorderPane { this.setCenter(tableArrayPane); pamFlipePane = new PamFlipPane(); - pamFlipePane.getAdvLabel().setText("Hydrophone Settings"); + pamFlipePane.getAdvLabel().setText("Streamer"); ((Pane) streamerPane.getContentNode()).setPadding(new Insets(5,5,5,15)); diff --git a/src/PamUtils/PamArrayUtils.java b/src/PamUtils/PamArrayUtils.java index 3fa34a5f..9d6b0730 100644 --- a/src/PamUtils/PamArrayUtils.java +++ b/src/PamUtils/PamArrayUtils.java @@ -449,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 @@ -476,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 @@ -490,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= 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; diff --git a/src/clickDetector/layoutFX/clickClassifiers/BasicIdentifierPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/BasicIdentifierPaneFX.java index becb7380..e2cf0f39 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/BasicIdentifierPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/BasicIdentifierPaneFX.java @@ -6,6 +6,7 @@ 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; @@ -108,6 +109,7 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX { protected Node createSettingsPane(){ mainHolderPane=new PamBorderPane(); + mainHolderPane.setPadding(new Insets(5,5,5,5)); mainHolderPane.setCenter(clickTypesTable=new ClickClassifierTable(clickClassifiers)); clickTypeHolder=new PamBorderPane(); diff --git a/src/clickDetector/layoutFX/clickClassifiers/ClickClassifyPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/ClickClassifyPaneFX.java index c71d55bd..cbc16c86 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/ClickClassifyPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/ClickClassifyPaneFX.java @@ -110,7 +110,7 @@ public class ClickClassifyPaneFX extends PamStackPane { //create the main pane. PamVBox holderPane=new PamVBox(); - // holderPane.setPadding(new Insets(5,5,5,5)); + holderPane.setPadding(new Insets(5,5,5,5)); holderPane.setSpacing(5); //create label diff --git a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierPaneFX.java index b099e835..a300684c 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierPaneFX.java @@ -8,7 +8,9 @@ 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. @@ -42,14 +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().getPreAdvLabel().graphicProperty().bind(sweepPane.getNameGraphicProperty()); - sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType()); sweepPane.setParams(clickTypeProperty); diff --git a/src/matchedTemplateClassifer/ImportTemplateCSV.java b/src/matchedTemplateClassifer/ImportTemplateCSV.java index 0713f026..69b1063e 100644 --- a/src/matchedTemplateClassifer/ImportTemplateCSV.java +++ b/src/matchedTemplateClassifer/ImportTemplateCSV.java @@ -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; diff --git a/src/matchedTemplateClassifer/MTClassifier.java b/src/matchedTemplateClassifer/MTClassifier.java index 476d4735..ddde2bc7 100644 --- a/src/matchedTemplateClassifer/MTClassifier.java +++ b/src/matchedTemplateClassifer/MTClassifier.java @@ -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; isR) { + if (waveformMatch.sRsR){ + //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); } diff --git a/src/matchedTemplateClassifer/MTProcess.java b/src/matchedTemplateClassifer/MTProcess.java index 32c46040..92e86a2f 100644 --- a/src/matchedTemplateClassifer/MTProcess.java +++ b/src/matchedTemplateClassifer/MTProcess.java @@ -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 results = new ArrayList(); - //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 diff --git a/src/matchedTemplateClassifer/layoutFX/MTSettingsPane.java b/src/matchedTemplateClassifer/layoutFX/MTSettingsPane.java index 2ca0748e..c9c545f6 100644 --- a/src/matchedTemplateClassifer/layoutFX/MTSettingsPane.java +++ b/src/matchedTemplateClassifer/layoutFX/MTSettingsPane.java @@ -328,7 +328,7 @@ public class MTSettingsPane extends SettingsPane { 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)); diff --git a/src/matchedTemplateClassifer/offline/MTClassifierOfflineTask.java b/src/matchedTemplateClassifer/offline/MTClassifierOfflineTask.java index 99b9ca68..f2544265 100644 --- a/src/matchedTemplateClassifer/offline/MTClassifierOfflineTask.java +++ b/src/matchedTemplateClassifer/offline/MTClassifierOfflineTask.java @@ -40,19 +40,31 @@ public class MTClassifierOfflineTask extends OfflineTask> { @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; + } diff --git a/src/pamViewFX/fxNodes/PamTabPane.java b/src/pamViewFX/fxNodes/PamTabPane.java index 261740d8..14ab8ab0 100644 --- a/src/pamViewFX/fxNodes/PamTabPane.java +++ b/src/pamViewFX/fxNodes/PamTabPane.java @@ -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; tabPaneSkin = new PamTabPaneSkin(this); } diff --git a/src/pamViewFX/fxNodes/flipPane/PamFlipPane.java b/src/pamViewFX/fxNodes/flipPane/PamFlipPane.java index 43530920..c5a12aaf 100644 --- a/src/pamViewFX/fxNodes/flipPane/PamFlipPane.java +++ b/src/pamViewFX/fxNodes/flipPane/PamFlipPane.java @@ -1,5 +1,8 @@ package pamViewFX.fxNodes.flipPane; +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; @@ -8,12 +11,16 @@ 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 @@ -146,22 +153,48 @@ public class PamFlipPane extends FlipPane { 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 TextField("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); - advLabel.setId("label-title2"); - advLabel.setStyle("-fx-background-color: transparent"); + advLabel.setAlignment(Pos.CENTER); - HBox.setHgrow(advLabel, Priority.ALWAYS); + HBox.setHgrow(titleHolder, Priority.ALWAYS); advPane.setTop(buttonHolder); diff --git a/src/pamViewFX/fxNodes/utilityPanes/FilterPaneFX.java b/src/pamViewFX/fxNodes/utilityPanes/FilterPaneFX.java index c758442f..33eb11c1 100644 --- a/src/pamViewFX/fxNodes/utilityPanes/FilterPaneFX.java +++ b/src/pamViewFX/fxNodes/utilityPanes/FilterPaneFX.java @@ -143,7 +143,7 @@ public class FilterPaneFX extends SettingsPane { } else { mainPane.setTop(createFilterPane()); - mainPane.setBottom(createBodeGraph()); + mainPane.setCenter(createBodeGraph()); } } diff --git a/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java b/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java index b80f2539..711491dd 100644 --- a/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java +++ b/src/pamViewFX/fxNodes/utilityPanes/LatLongPane.java @@ -8,6 +8,7 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.control.Toggle; import javafx.scene.control.ToggleButton; import javafx.scene.text.TextAlignment; import pamViewFX.PamGuiManagerFX; @@ -47,6 +48,11 @@ public class LatLongPane extends SettingsPane{ private ToggleButton decimal; + /** + * Segmented button that also selection of the latitude and longitude format type. + */ + private SegmentedButton segmentedButton; + public LatLongPane(String title) { super(null); @@ -71,7 +77,7 @@ public class LatLongPane extends SettingsPane{ minutesSeconds = new ToggleButton("Degrees, Minutes, Seconds"); decimal = new ToggleButton("Decimal"); - SegmentedButton segmentedButton = new SegmentedButton(); + segmentedButton = new SegmentedButton(); segmentedButton.getButtons().addAll(decimalMinutes, minutesSeconds, decimal); PamHBox top = new PamHBox(); @@ -109,6 +115,7 @@ public class LatLongPane extends SettingsPane{ mainPane.getChildren().add(cent); + decimal.setSelected(true); } @@ -144,18 +151,20 @@ public class LatLongPane extends SettingsPane{ 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.setValue(latLong.getLatitude()); - longStrip.setValue(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()); } @@ -165,6 +174,21 @@ public class LatLongPane extends SettingsPane{ */ @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; diff --git a/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java b/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java index d8a3f368..2e80e8f0 100644 --- a/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java +++ b/src/pamViewFX/fxNodes/utilityPanes/LatLongStrip.java @@ -75,17 +75,22 @@ public class LatLongStrip extends PamBorderPane { // 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(); nsew.setOnAction((action)->{ @@ -152,25 +157,35 @@ public class LatLongStrip extends PamBorderPane { 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) { - setValue(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) { + + if (formatType==formatStyle) { + return; + } + + //important this comes before setting format style. + double currentValue = getValue(); this.formatType = formatStyle; degHBox.getChildren().clear(); + + System.out.println("FORMATSTYLE: " + formatStyle + " val " + currentValue); - System.out.println("FORMATSTYLE: " + formatStyle); switch (formatType) { case LatLong.FORMAT_DECIMALMINUTES: degHBox.getChildren().add(dl); @@ -192,7 +207,9 @@ public class LatLongStrip extends PamBorderPane { break; } - + + setValue(currentValue); + sayFormattedValue(getValue()); } @@ -205,6 +222,8 @@ public class LatLongStrip extends PamBorderPane { } public void setValue(double value, boolean hiddenOnly) { + + System.out.println("Set value: " + value); if (value >= 0) { nsew.getSelectionModel().select(0); } @@ -249,18 +268,20 @@ public class LatLongStrip extends PamBorderPane { } /** - * 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 (LatLong.getFormatStyle() == LatLong.FORMAT_DECIMAL){ + if (formatType == LatLong.FORMAT_DECIMAL){ try { deg = Double.valueOf(decimal.getText()); return deg; @@ -278,7 +299,7 @@ public class LatLongStrip extends PamBorderPane { } - if (LatLong.getFormatStyle() == LatLong.FORMAT_DECIMALMINUTES){ + if (formatType == LatLong.FORMAT_DECIMALMINUTES){ try { min = Double.valueOf(decminutes.getText()); } @@ -355,4 +376,6 @@ public class LatLongStrip extends PamBorderPane { public Label getTitleLabel() { return titleLabel; } + + } diff --git a/src/pamViewFX/fxNodes/utilsFX/TextUtilsFX.java b/src/pamViewFX/fxNodes/utilsFX/TextUtilsFX.java new file mode 100644 index 00000000..d47098d7 --- /dev/null +++ b/src/pamViewFX/fxNodes/utilsFX/TextUtilsFX.java @@ -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; + } +} \ No newline at end of file