From 9469737ea1f7be96e4378dd5a9bde719769c7a30 Mon Sep 17 00:00:00 2001 From: Jamie Mac Date: Tue, 16 Jul 2024 17:40:45 +0100 Subject: [PATCH] Updates to deep learning symbol options for swing and data selector panel for swing Made tooltips last longer on TD display FX --- .../dataSelector/CompoundDataSelector.java | 3 + .../DataSelectorDialogPaneFX.java | 17 +- src/Spectrogram/ColourRangeSlider.java | 9 +- src/Spectrogram/ColourRangeSliderUI.java | 108 +++++- .../clickPlotFX/ClickControlPane2.java | 4 +- src/dataPlotsFX/layout/TDGraphFX.java | 5 +- src/pamViewFX/fxNodes/utilsFX/PamUtilsFX.java | 9 + .../dataPlotFX/DLPredictionPane.java | 4 +- .../dataPlotFX/DLSymbolModifier.java | 37 +- .../dataPlotFX/DLSymbolOptionPane.java | 8 +- .../dataPlotFX/DLSymbolOptionPanel.java | 338 ++++++++++++++++++ .../dataSelector/DLPredictionFilter.java | 2 +- .../dataSelector/DLPredictionPanel.java | 154 +++++++- .../dataSelector/DLPredictonPane.java | 12 +- .../dataSelector/DLSelectPanel.java | 69 +++- 15 files changed, 725 insertions(+), 54 deletions(-) create mode 100644 src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPanel.java diff --git a/src/PamguardMVC/dataSelector/CompoundDataSelector.java b/src/PamguardMVC/dataSelector/CompoundDataSelector.java index 78effad5..67c58d2d 100644 --- a/src/PamguardMVC/dataSelector/CompoundDataSelector.java +++ b/src/PamguardMVC/dataSelector/CompoundDataSelector.java @@ -95,6 +95,9 @@ public class CompoundDataSelector extends DataSelector { score = Math.max(score, score2); // take the largest } } + +// System.out.println("Hello Compound Data selector: " + score); + return score; } diff --git a/src/PamguardMVC/dataSelector/DataSelectorDialogPaneFX.java b/src/PamguardMVC/dataSelector/DataSelectorDialogPaneFX.java index bcfa7aeb..3782ed88 100644 --- a/src/PamguardMVC/dataSelector/DataSelectorDialogPaneFX.java +++ b/src/PamguardMVC/dataSelector/DataSelectorDialogPaneFX.java @@ -91,10 +91,19 @@ public class DataSelectorDialogPaneFX extends DynamicSettingsPane { } - andButton.setOnAction(event -> enableComponent()); - orButton.setOnAction(event -> enableComponent()); - disableButton.setOnAction(event -> enableComponent()); - + andButton.setOnAction(event -> { + enableComponent(); + notifySettingsListeners(); + }); + orButton.setOnAction(event ->{ + enableComponent(); + notifySettingsListeners(); + }); + disableButton.setOnAction(event ->{ + enableComponent(); + notifySettingsListeners(); + }); + buttonPane = new HBox(); // Use HBox for horizontal button layout buttonPane.setSpacing(5); buttonPane.setAlignment(Pos.CENTER); diff --git a/src/Spectrogram/ColourRangeSlider.java b/src/Spectrogram/ColourRangeSlider.java index c5e851c1..14e26b0e 100644 --- a/src/Spectrogram/ColourRangeSlider.java +++ b/src/Spectrogram/ColourRangeSlider.java @@ -15,10 +15,17 @@ public class ColourRangeSlider extends PamRangeSlider { public ColourRangeSlider(){ super(JSlider.VERTICAL); +// this.orientation = JSlider.VERTICAL; } public ColourRangeSlider(int min, int max){ - super(min,max, JSlider.VERTICAL); + super(JSlider.VERTICAL); +// this.orientation = JSlider.HORIZONTAL; + } + + public ColourRangeSlider(int orientation){ + super(orientation); +// this.orientation = JSlider.HORIZONTAL; } public void setColourMap(ColourArrayType colourMap){ diff --git a/src/Spectrogram/ColourRangeSliderUI.java b/src/Spectrogram/ColourRangeSliderUI.java index 808aa6a4..884db474 100644 --- a/src/Spectrogram/ColourRangeSliderUI.java +++ b/src/Spectrogram/ColourRangeSliderUI.java @@ -8,8 +8,7 @@ import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; - - +import javax.swing.JSlider; import PamView.ColourArray; import PamView.ColourArray.ColourArrayType; @@ -78,6 +77,8 @@ public class ColourRangeSliderUI extends PamRangeSliderUI { private void createColourMapImage(){ + if (b.getOrientation() == JSlider.VERTICAL) { + // now make a standard amplitude image if (colourArray != null && colourArray.length > 0) { amplitudeImage = new BufferedImage(1, colourArray.length, @@ -87,6 +88,15 @@ public class ColourRangeSliderUI extends PamRangeSliderUI { raster.setPixel(0, colourArray.length - i - 1, colourArray[i]); } } + } + else { + amplitudeImage = new BufferedImage(colourArray.length, 1, + BufferedImage.TYPE_INT_RGB); + WritableRaster raster = amplitudeImage.getRaster(); + for (int i = 0; i < colourArray.length; i++) { + raster.setPixel(i, 0,colourArray[i]); + } + } } @@ -119,26 +129,98 @@ public class ColourRangeSliderUI extends PamRangeSliderUI { Rectangle trackBounds = trackRect; - // Determine position of selected range by moving from the middle - // of one thumb to the other. - int lowerY = thumbRect.y + (thumbRect.width / 2); - int upperY = getUpperThumbRect().y + (getUpperThumbRect().width / 2); - - // Determine track position. - int cx = (trackBounds.width / 2) - 2; - // Save colour and shift position. Color oldColor = g.getColor(); - g.translate(trackBounds.x + cx, trackBounds.y); - drawColourMapVert( g, lowerY - trackBounds.y, upperY - trackBounds.y, -(getUpperThumbRect().width /4)-trackBounds.x,(getUpperThumbRect().width / 2)-trackBounds.x+(trackBounds.width / 4)+2); + int cx; + if (b.getOrientation() == JSlider.VERTICAL) { + + // Determine position of selected range by moving from the middle + // of one thumb to the other. + int lowerY = thumbRect.y + (thumbRect.width / 2); + int upperY = getUpperThumbRect().y + (getUpperThumbRect().width / 2); + + // Determine track position. + cx = (trackBounds.width / 2) - 2; + + g.translate(trackBounds.x + cx, trackBounds.y); + drawColourMapVert( g, lowerY - trackBounds.y, upperY - trackBounds.y, -(getUpperThumbRect().width /4)-trackBounds.x,(getUpperThumbRect().width / 2)-trackBounds.x+(trackBounds.width / 4)+2); + + cx = (trackBounds.width / 2) - 2; + g.translate(-(trackBounds.x + cx), -trackBounds.y); + + } + else { + // Determine position of selected range by moving from the middle + // of one thumb to the other. + int lowerX = thumbRect.x; + int upperX = getUpperThumbRect().x; + + // Determine track position. + cx = (trackBounds.width / 2) - 2; +// -(getUpperThumbRect().height /4)-trackBounds.y, (getUpperThumbRect().height / 2)-trackBounds.y+(trackBounds.height / 4)+2 + drawColourMapHorz(g, trackBounds.height/2-getUpperThumbRect().height/2, trackBounds.height/2+getUpperThumbRect().height/2, lowerX + getUpperThumbRect().width/2, upperX+ getUpperThumbRect().width/2); + + } // Restore position and colour. - g.translate(-(trackBounds.x + cx), -trackBounds.y); g.setColor(oldColor); } + /** + * Draw the colour map between the two thumbs in the slider bar. Colour the section above the top most thumb + * and the section below the lower most thumb with the color map extremes. + * @param g- graphics + * @param y1 + * @param y2 + * @param x1 + * @param x2 + */ + private void drawColourMapHorz(Graphics g, int y1, int y2, int x1, int x2){ + + if (amplitudeImage == null) return; + + Graphics2D g2d = (Graphics2D) g; + + int width=Math.abs(x2-x1); + int height=Math.abs(y2-y1); + +// System.out.println("Width: " + width + " " + height + " x1 " + x1); + + //calculate the distance between thumbs + double ascaleX = width + / (double) amplitudeImage.getWidth(null); + double ascaleY = height + / (double) amplitudeImage.getHeight(null); + + AffineTransform xform = new AffineTransform(); + // xform.translate(1, amplitudeImage.getWidth(null)); + xform.scale(ascaleX, ascaleY); + //translate to the correct location; + g2d.translate(x1, y1); + //now translate back for the rest of the operations; + g2d.drawImage(amplitudeImage, xform, b); + + //translate back to our original position. + g2d.translate(-x1, -y1); + + //go to the left of the lower thumb; +// g2d.translate(0, height); + g2d.setColor(new Color((int) colourArray[0][0],(int)colourArray[0][1],(int) colourArray[0][2])); + for (int i=y1; i("Min", "Max" , "", 2, 100, 1); + minMaxWidthPane = new DualControlField("", "" , "", 2, 100, 1); minMaxWidthPane.addChangeListener((obsval, oldval, newval)->{ newSettings(); //do not allow the min ti be larger than the max. @@ -481,7 +481,7 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane { //height pane - minMaxHeightPane = new DualControlField("Min", "Max" , "", 2, 100, 1); + minMaxHeightPane = new DualControlField("", "" , "", 2, 100, 1); minMaxHeightPane.addChangeListener((obsval, oldval, newval)->{ newSettings(); //do not allow the min ti be larger than the max. diff --git a/src/dataPlotsFX/layout/TDGraphFX.java b/src/dataPlotsFX/layout/TDGraphFX.java index a0fa1dc5..b3ca0514 100644 --- a/src/dataPlotsFX/layout/TDGraphFX.java +++ b/src/dataPlotsFX/layout/TDGraphFX.java @@ -901,13 +901,14 @@ public class TDGraphFX extends PamBorderPane { } /** - * A tgool tip for detections. + * A Tooltip for showing information about detections. * * @author Jamie Macaulay * */ private class TDTooltip extends Tooltip { + private static final double TOOL_TIP_DELAY = 60; //seconds private TDPlotPane plotPanel; /** @@ -917,6 +918,8 @@ public class TDGraphFX extends PamBorderPane { public TDTooltip(TDPlotPane aPlot) { super("Test tooltip"); this.plotPanel = aPlot; + //make the Tooltip last a little longer + this.setShowDelay(Duration.seconds(TOOL_TIP_DELAY)); /* * See https://bugs.openjdk.java.net/browse/JDK-8090477 fr info about tool tip * timing on these displys. diff --git a/src/pamViewFX/fxNodes/utilsFX/PamUtilsFX.java b/src/pamViewFX/fxNodes/utilsFX/PamUtilsFX.java index 98efc95b..34507674 100644 --- a/src/pamViewFX/fxNodes/utilsFX/PamUtilsFX.java +++ b/src/pamViewFX/fxNodes/utilsFX/PamUtilsFX.java @@ -19,7 +19,9 @@ import javax.swing.JRadioButtonMenuItem; import javax.swing.JSeparator; import javax.swing.SwingUtilities; +import PamView.ColourArray.ColourArrayType; import PamView.PamSymbol; +import PamView.PamView; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; @@ -54,6 +56,13 @@ import pamViewFX.fxNodes.PamSymbolFX; */ public class PamUtilsFX { + + public static ColourArrayType fxColArray2Swing(pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType arrayFX) { + + ColourArrayType type = ColourArrayType.valueOf(arrayFX.toString()); + + return type; + } /** * * @param awtColor diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLPredictionPane.java b/src/rawDeepLearningClassifier/dataPlotFX/DLPredictionPane.java index 19147c81..2d05d4af 100644 --- a/src/rawDeepLearningClassifier/dataPlotFX/DLPredictionPane.java +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLPredictionPane.java @@ -19,7 +19,9 @@ import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch; import rawDeepLearningClassifier.dlClassification.DLClassName; /* - * Symbol Options for the annotation pane + * Symbol Options for the annotation pane. + * + * @author Jamie Macaulay */ public class DLPredictionPane extends PamBorderPane implements TDSettingsPane { diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolModifier.java b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolModifier.java index 6e6bc752..4b2a32e3 100644 --- a/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolModifier.java +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolModifier.java @@ -1,10 +1,14 @@ package rawDeepLearningClassifier.dataPlotFX; import java.awt.Color; +import java.awt.event.ActionEvent; +import PamController.PamController; import PamUtils.PamArrayUtils; import PamView.GeneralProjector; import PamView.PamSymbolType; +import PamView.dialog.GenericSwingDialog; +import PamView.dialog.PamDialogPanel; import PamView.symbol.PamSymbolChooser; import PamView.symbol.SymbolData; import PamView.symbol.modifier.SymbolModType; @@ -21,10 +25,10 @@ import rawDeepLearningClassifier.logging.DLAnnotationType; /** - * The DL symbol modifier. Colours symbols by eother the vlaue of the prediction by a user selected class - * or by the class with the highest prediction value. + * The DL symbol modifier. Colours symbols by either the value of the prediction + * by a user selected class or by the class with the highest prediction value. * - * @author Jamie Macaulay. + * @author Jamie Macaulay. * */ public class DLSymbolModifier extends SymbolModifier { @@ -38,12 +42,12 @@ public class DLSymbolModifier extends SymbolModifier { /** - * The symbol options pane. + * JavaFX symbol options pane. */ private DLSymbolOptionPane optionsPane; /** - * Rge DL annotation type. + * The DL annotation type. */ private DLAnnotationType dlAnnotType; @@ -57,6 +61,11 @@ public class DLSymbolModifier extends SymbolModifier { private ColourArray colourArray; + /** + * Swing option panel for the symbol chooser. + */ + private DLSymbolOptionPanel optionsPanel; + public DLSymbolModifier(PamSymbolChooser symbolChooser, DLAnnotationType dlAnnotType) { @@ -226,6 +235,7 @@ public class DLSymbolModifier extends SymbolModifier { * Get the JavaFX symbol options pane that has options for the symbol pane. * @return the symbol options pane. */ + @Override public SymbolModifierPane getOptionsPane() { if (optionsPane == null) { optionsPane = new DLSymbolOptionPane(this); @@ -233,6 +243,23 @@ public class DLSymbolModifier extends SymbolModifier { return optionsPane; } + @Override + public PamDialogPanel getDialogPanel() { + if (optionsPanel == null) { + optionsPanel = new DLSymbolOptionPanel(this); + } + return optionsPanel; + } + + /** + * Default behaviour to show the dialog panel. + * @param e + * @param dialogPanel + */ + protected void showOptionsDialog(ActionEvent e, PamDialogPanel dialogPanel) { + GenericSwingDialog.showDialog(PamController.getMainFrame(), getName() + " options", dialogPanel); + } + public DLAnnotationType getDLAnnotType() { return dlAnnotType; diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPane.java b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPane.java index 13eb8aab..32830c4a 100644 --- a/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPane.java +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPane.java @@ -29,7 +29,9 @@ import rawDeepLearningClassifier.dlClassification.DLClassName; /* - * Symbol Options for the annotation pane + * Symbol Options for the annotation pane. + * + * @author Jamie Macaulay */ public class DLSymbolOptionPane extends StandardSymbolModifierPane { @@ -390,11 +392,11 @@ public class DLSymbolOptionPane extends StandardSymbolModifierPane { // b1.setSelected(false); // b2.setSelected(false); if (symbolOptions.colTypeSelection == DLSymbolModifierParams.PREDICITON_COL) b1.setSelected(true); - if (symbolOptions.colTypeSelection == DLSymbolModifierParams.PREDICITON_COL) b2.setSelected(true); + if (symbolOptions.colTypeSelection == DLSymbolModifierParams.CLASS_COL) b2.setSelected(true); setSettingsPane(); - symbolOptions.colTypeSelection = b1.isSelected() ? DLSymbolModifierParams.PREDICITON_COL : DLSymbolModifierParams.CLASS_COL; +// symbolOptions.colTypeSelection = b1.isSelected() ? DLSymbolModifierParams.PREDICITON_COL : DLSymbolModifierParams.CLASS_COL; //set the parameters for colouring by prediction setPredictionColParams(symbolOptions); diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPanel.java b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPanel.java new file mode 100644 index 00000000..e2da15ac --- /dev/null +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLSymbolOptionPanel.java @@ -0,0 +1,338 @@ +package rawDeepLearningClassifier.dataPlotFX; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JColorChooser; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.JToggleButton; +import javax.swing.border.TitledBorder; + +import PamView.ColourComboBox; +import PamView.dialog.GenericSwingDialog; +import PamView.dialog.PamButton; +import PamView.dialog.PamDialogPanel; +import PamView.panel.PamPanel; +import PamView.symbol.modifier.SymbolModifier; +import Spectrogram.ColourRangeSlider; +import pamViewFX.fxNodes.utilsFX.PamUtilsFX; +import rawDeepLearningClassifier.dlClassification.DLClassName; + +/** + * + * Swing symbol options for the annotation pane. + * + * @author Jamie Macaulay + */ +public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener { + + private static final long serialVersionUID = 1L; + + private static final double CLASS_NAME_BOX_WIDTH = 130; + + private DLSymbolModifier dlSymbolModifier; + + /** + * The color range slider for coloring probabilities. + */ + private ColourRangeSlider colorRangeSlider; + + /** + * The combo box allowing users to select which class to show. + */ + private JComboBox classNameBox; + private JComboBox classNameBox2; + + /** + * Check box allowing users only to show only those detections which have passed binary classification. + */ + private JCheckBox showOnlyBinary; + + /** + * Color picker which allows a user to select the gradient for coloring predictions + */ + private ColourComboBox colorComboBox; + + /** + * Color picker which allows a user to select color for each class. + */ + private JColorChooser colorPicker; + + private boolean initialized = true; + + /** + * Pane which holds controls for changing the colour based on prediciton value + */ + private JPanel probPane; + + /** + * Pane which holds controls for changing the colour based on the highest prediction value + */ + private JPanel classPane; + + private PamPanel holder; + + /** + * Button to select how to colour. + */ + private JToggleButton b1, b2; + + private PamPanel mainPanel; + + + public DLSymbolOptionPanel(SymbolModifier symbolModifer) { + this.dlSymbolModifier = (DLSymbolModifier) symbolModifer; + + probPane = createProbPane(); + probPane.setBorder(new TitledBorder("Colour by prediction value")); + + classPane = createClassPane(); + classPane.setBorder(new TitledBorder("Colour by class")); + + b1 = new JToggleButton("Prediction"); + b1.setPreferredSize(new Dimension(100, 25)); // Set preferred size + + b2 = new JToggleButton("Class"); + b2.setPreferredSize(new Dimension(100, 25)); + + ButtonGroup buttonGroup = new ButtonGroup(); // Group toggle buttons + buttonGroup.add(b1); + buttonGroup.add(b2); + + b1.addActionListener(this); + b2.addActionListener(this); + + JPanel segmentedButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + segmentedButtonPanel.add(b1); + segmentedButtonPanel.add(b2); + + holder = new PamPanel(); + holder.setLayout(new BorderLayout()); + holder.add(new JLabel("Hello"), BorderLayout.NORTH); + + mainPanel = new PamPanel(); + mainPanel.setLayout(new BorderLayout()); + + mainPanel.add(segmentedButtonPanel, BorderLayout.NORTH); + mainPanel.add(holder, BorderLayout.CENTER); + mainPanel.add(showOnlyBinary = new JCheckBox("Show only binary classification"), BorderLayout.SOUTH); + + setSettingsPane(); + + initialized = true; + } + + @Override + public JComponent getDialogComponent() { + return mainPanel; + } + + @Override + public void setParams() { + //get the symbool options + DLSymbolModifierParams symbolOptions = dlSymbolModifier.getSymbolModifierParams(); + + // b1.setSelected(false); + // b2.setSelected(false); + if (symbolOptions.colTypeSelection == DLSymbolModifierParams.PREDICITON_COL) b1.setSelected(true); + if (symbolOptions.colTypeSelection == DLSymbolModifierParams.CLASS_COL) b2.setSelected(true); + + setSettingsPane(); + + //set the parameters for colouring by prediction + setPredictionColParams(symbolOptions); + + //set the class colour parameters + setClassColParams(symbolOptions); + + //set the selected. + showOnlyBinary.setSelected(symbolOptions.showOnlyBinary); + + setSettingsPane(); + } + + + private int checkClassNamesBox(DLSymbolModifierParams symbolOptions, JComboBox classNameBox) { + + DLClassName[] classNames = dlSymbolModifier.getDLAnnotType().getDlControl().getDLModel().getClassNames(); + + // for (int i =0; ii) { + classNameBox.addItem(classNames[i].className); + } + else { + classNameBox.addItem("Class: " + i); + } + } + + return nClass; + + } + + + /** + * Set parameters for controls to change the colour gradient based on prediction. + * @param symbolOptions - the symbol options + */ + private void setPredictionColParams(DLSymbolModifierParams symbolOptions) { + + //now set frequency parameters + colorRangeSlider.setValue((int) symbolOptions.clims[0]*100); + colorRangeSlider.setUpperValue((int) symbolOptions.clims[1]*100); + // colorRangeSlider.setColourArrayType( symbolOptions.colArray); + + colorRangeSlider.setColourMap(PamUtilsFX.fxColArray2Swing(symbolOptions.colArray)); + + + int nClass = checkClassNamesBox( symbolOptions, classNameBox); + + symbolOptions.classIndex = Math.min(symbolOptions.classIndex, nClass-1); + classNameBox.setSelectedIndex(Math.max(symbolOptions.classIndex, 0)); + + //color box. + colorComboBox.setSelectedColourMap(PamUtilsFX.fxColArray2Swing(symbolOptions.colArray)); + } + + /** + * Set parameters for controls to change the colour gradient based on prediction. + * @param symbolOptions - the symbol options + */ + private void setClassColParams(DLSymbolModifierParams symbolOptions) { + + int nClass = checkClassNamesBox( symbolOptions, classNameBox2); + + symbolOptions.classIndex = Math.min(symbolOptions.classIndex, nClass-1); + + classNameBox2.setSelectedIndex(Math.max(symbolOptions.classIndex2, 0)); + + + int index = symbolOptions.classIndex2>=0 ? symbolOptions.classIndex2 : 0; + + if (symbolOptions.classColors==null) { + symbolOptions.setDefaultClassColors(nClass); + } + + // //set the correct colour + // colorPicker.setColor(symbolOptions.classColors[index]); + } + + + @Override + public boolean getParams() { + // TODO Auto-generated method stub + return false; + } + + + private void setSettingsPane() { + holder.removeAll(); + //holder.setLayout(new BorderLayout()); + holder.validate(); + + if (b1.isSelected()) { + holder.add(probPane, BorderLayout.CENTER); + System.out.println("Set probPane pane"); + } else if (b2.isSelected()) { + holder.add(classPane, BorderLayout.CENTER); + System.out.println("Set class pane"); + } + + holder.validate(); + mainPanel.validate(); + + if (mainPanel.getRootPane()!=null) { + //pack the dialog because it is a different size + ((GenericSwingDialog) mainPanel.getRootPane().getParent()).pack(); + } + } + + + private JPanel createClassPane() { + + classNameBox2 = new JComboBox<>(); + classNameBox2.addActionListener(this); + classNameBox2.setPreferredSize(new Dimension((int) CLASS_NAME_BOX_WIDTH, 25)); + + // colorPicker.setPreferredSize(new Dimension(60, 25)); + + PamButton colourButton = new PamButton("Color"); + colourButton.addActionListener((action)->{ + Color color = JColorChooser.showDialog(colourButton, "Pick colour for class", Color.black); + colourButton.setBackground(color); + // colourButton.setForeground(color); + }); + + JPanel classHolder = new JPanel(); + FlowLayout flowLayout = new FlowLayout(); + classHolder.setLayout(flowLayout); + + classHolder.add(classNameBox2); + classHolder.add(colourButton); + + return classHolder; + } + + + private PamPanel createProbPane() { + PamPanel holder = new PamPanel(); + holder.setLayout(new GridBagLayout()); + + GridBagConstraints c = new GridBagConstraints(); + + c.gridx = 0; + c.gridy = 0; + + holder.add(new JLabel("Select class"), c); + + c.gridx++; + classNameBox = new JComboBox(); + holder.add(classNameBox, c); + + c.gridx = 0; + c.gridwidth = 1; + c.gridy++; + holder.add(new JLabel("Color map"), c); + + c.gridx++; + colorComboBox = new ColourComboBox(); + holder.add(colorComboBox, c); + + c.gridx = 0; + c.gridy++; + c.gridwidth =2; + colorRangeSlider = new ColourRangeSlider(JSlider.HORIZONTAL); // Min 0, Max 1 for probabilities + colorRangeSlider.setPaintTicks(true); + holder.add(colorRangeSlider, c); + + return holder; + } + + @Override + public void actionPerformed(ActionEvent e) { + setSettingsPane(); + } + +} diff --git a/src/rawDeepLearningClassifier/dataSelector/DLPredictionFilter.java b/src/rawDeepLearningClassifier/dataSelector/DLPredictionFilter.java index 1d05f030..403c0d45 100644 --- a/src/rawDeepLearningClassifier/dataSelector/DLPredictionFilter.java +++ b/src/rawDeepLearningClassifier/dataSelector/DLPredictionFilter.java @@ -65,7 +65,7 @@ public class DLPredictionFilter implements DLDataFilter { } @Override - public DataSelectParams getParams() { + public DLPredictionFilterParams getParams() { checkParamsClass() ; return filterParams; } diff --git a/src/rawDeepLearningClassifier/dataSelector/DLPredictionPanel.java b/src/rawDeepLearningClassifier/dataSelector/DLPredictionPanel.java index 98b4b973..00db7439 100644 --- a/src/rawDeepLearningClassifier/dataSelector/DLPredictionPanel.java +++ b/src/rawDeepLearningClassifier/dataSelector/DLPredictionPanel.java @@ -1,34 +1,178 @@ package rawDeepLearningClassifier.dataSelector; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JCheckBox; import javax.swing.JComponent; +import javax.swing.JSpinner; +import javax.swing.JToggleButton; +import javax.swing.SpinnerNumberModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import org.kordamp.ikonli.materialdesign2.MaterialDesignL; +import org.kordamp.ikonli.swing.FontIcon; import PamView.dialog.PamDialogPanel; +import PamView.dialog.PamGridBagContraints; +import PamView.panel.PamPanel; +import rawDeepLearningClassifier.dlClassification.DLClassName; /** * Swing panel for Deep learning predicitons. */ public class DLPredictionPanel implements PamDialogPanel { + private DLPredictionFilter predicitonFilter; + + private PamPanel contentPanel; + + private JCheckBox[] enableClass; + + private JSpinner[] spinnerClass; + + private JToggleButton lockButton; + + public DLPredictionPanel(DLPredictionFilter dlPredictionFilter) { super(); + this.predicitonFilter = dlPredictionFilter; + + contentPanel = new PamPanel(); + contentPanel.setLayout(new GridBagLayout()); + + lockButton = new JToggleButton(); + + FontIcon iconlock = FontIcon.of(MaterialDesignL.LOCK); + iconlock.setIconSize(20); + iconlock.setIconColor(Color.DARK_GRAY); + + FontIcon iconlockopen = FontIcon.of(MaterialDesignL.LOCK_OPEN); + iconlockopen.setIconSize(20); + iconlockopen.setIconColor(Color.DARK_GRAY); + + lockButton.setIcon(iconlockopen); + + lockButton.addActionListener((action)->{ + if (lockButton.isSelected()) { + lockButton.setIcon(iconlock); + } + else { + lockButton.setIcon(iconlockopen); + } + lockButton.validate(); + }); + + } @Override public JComponent getDialogComponent() { - // TODO Auto-generated method stub - return null; + return contentPanel; } @Override public void setParams() { + + DLPredictionFilterParams params = predicitonFilter.getParams(); // TODO Auto-generated method stub - + setClassPane(params); + + for (int i=0; i{ + spinnerClass[ii].setEnabled(enableClass[ii].isSelected()); + }); + enableClass[i].setToolTipText(classNames[i].className); + contentPanel.add(enableClass[i], c); + + c.gridx = 1; + + + spinnerClass[i] = new JSpinner(new SpinnerNumberModel(0., 0., 1., 0.05)); + + Dimension prefSize = spinnerClass[i].getPreferredSize(); + prefSize = new Dimension(60, prefSize.height); + spinnerClass[i] .setPreferredSize(prefSize); + + spinnerClass[i].addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (lockButton.isSelected()) { + for (int j=0; j1) { + //set a lock button to + c.gridx=2; + contentPanel.add(lockButton, c); + + //make the lock button the same height as the spinner + Dimension prefSizeB = lockButton.getPreferredSize(); + lockButton.setPreferredSize(new Dimension(prefSizeB.width, prefSize.height)); + + } + + c.gridy++; + + + } + + contentPanel.validate(); } @Override public boolean getParams() { - // TODO Auto-generated method stub - return false; + + DLPredictionFilterParams currParams = predicitonFilter.getParams(); + + for (int i=0; i