Updates to deep learning symbol options for swing and data selector panel for swing

Made tooltips last longer on TD display  FX
This commit is contained in:
Jamie Mac 2024-07-16 17:40:45 +01:00
parent 91c0b45b45
commit 9469737ea1
15 changed files with 725 additions and 54 deletions

View File

@ -95,6 +95,9 @@ public class CompoundDataSelector extends DataSelector {
score = Math.max(score, score2); // take the largest score = Math.max(score, score2); // take the largest
} }
} }
// System.out.println("Hello Compound Data selector: " + score);
return score; return score;
} }

View File

@ -91,9 +91,18 @@ public class DataSelectorDialogPaneFX extends DynamicSettingsPane<Boolean> {
} }
andButton.setOnAction(event -> enableComponent()); andButton.setOnAction(event -> {
orButton.setOnAction(event -> enableComponent()); enableComponent();
disableButton.setOnAction(event -> enableComponent()); notifySettingsListeners();
});
orButton.setOnAction(event ->{
enableComponent();
notifySettingsListeners();
});
disableButton.setOnAction(event ->{
enableComponent();
notifySettingsListeners();
});
buttonPane = new HBox(); // Use HBox for horizontal button layout buttonPane = new HBox(); // Use HBox for horizontal button layout
buttonPane.setSpacing(5); buttonPane.setSpacing(5);

View File

@ -15,10 +15,17 @@ public class ColourRangeSlider extends PamRangeSlider {
public ColourRangeSlider(){ public ColourRangeSlider(){
super(JSlider.VERTICAL); super(JSlider.VERTICAL);
// this.orientation = JSlider.VERTICAL;
} }
public ColourRangeSlider(int min, int max){ 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){ public void setColourMap(ColourArrayType colourMap){

View File

@ -8,8 +8,7 @@ import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster; import java.awt.image.WritableRaster;
import javax.swing.JSlider;
import PamView.ColourArray; import PamView.ColourArray;
import PamView.ColourArray.ColourArrayType; import PamView.ColourArray.ColourArrayType;
@ -78,6 +77,8 @@ public class ColourRangeSliderUI extends PamRangeSliderUI {
private void createColourMapImage(){ private void createColourMapImage(){
if (b.getOrientation() == JSlider.VERTICAL) {
// now make a standard amplitude image // now make a standard amplitude image
if (colourArray != null && colourArray.length > 0) { if (colourArray != null && colourArray.length > 0) {
amplitudeImage = new BufferedImage(1, colourArray.length, amplitudeImage = new BufferedImage(1, colourArray.length,
@ -88,6 +89,15 @@ public class ColourRangeSliderUI extends PamRangeSliderUI {
} }
} }
} }
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]);
}
}
}
private void createColours() { private void createColours() {
@ -119,26 +129,98 @@ public class ColourRangeSliderUI extends PamRangeSliderUI {
Rectangle trackBounds = trackRect; Rectangle trackBounds = trackRect;
// Save colour and shift position.
Color oldColor = g.getColor();
int cx;
if (b.getOrientation() == JSlider.VERTICAL) {
// Determine position of selected range by moving from the middle // Determine position of selected range by moving from the middle
// of one thumb to the other. // of one thumb to the other.
int lowerY = thumbRect.y + (thumbRect.width / 2); int lowerY = thumbRect.y + (thumbRect.width / 2);
int upperY = getUpperThumbRect().y + (getUpperThumbRect().width / 2); int upperY = getUpperThumbRect().y + (getUpperThumbRect().width / 2);
// Determine track position. // Determine track position.
int cx = (trackBounds.width / 2) - 2; cx = (trackBounds.width / 2) - 2;
// Save colour and shift position.
Color oldColor = g.getColor();
g.translate(trackBounds.x + cx, trackBounds.y); 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); drawColourMapVert( g, lowerY - trackBounds.y, upperY - trackBounds.y, -(getUpperThumbRect().width /4)-trackBounds.x,(getUpperThumbRect().width / 2)-trackBounds.x+(trackBounds.width / 4)+2);
// Restore position and colour. cx = (trackBounds.width / 2) - 2;
g.translate(-(trackBounds.x + cx), -trackBounds.y); 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.setColor(oldColor); 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<y2; i++){
g2d.drawLine(0,i,x1, i);
}
//color left of the thumb
g2d.setColor(new Color((int) colourArray[colourArray.length-1][0],(int)colourArray[colourArray.length-1][1],(int) colourArray[colourArray.length-1][2]));
for (int i=y1; i<y2; i++){
g2d.drawLine(x2,i, trackRect.width + thumbRect.width/2, i);
}
}
/** /**
* Draw the colour map between the two thumbs in the slider bar. Colour the section above the top most thumb * 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. * and the section below the lower most thumb with the color map extremes.

View File

@ -458,7 +458,7 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane {
PamVBox vBox = new PamVBox(); PamVBox vBox = new PamVBox();
vBox.setSpacing(5); vBox.setSpacing(5);
minMaxWidthPane = new DualControlField<Double>("Min", "Max" , "", 2, 100, 1); minMaxWidthPane = new DualControlField<Double>("", "" , "", 2, 100, 1);
minMaxWidthPane.addChangeListener((obsval, oldval, newval)->{ minMaxWidthPane.addChangeListener((obsval, oldval, newval)->{
newSettings(); newSettings();
//do not allow the min ti be larger than the max. //do not allow the min ti be larger than the max.
@ -481,7 +481,7 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane {
//height pane //height pane
minMaxHeightPane = new DualControlField<Double>("Min", "Max" , "", 2, 100, 1); minMaxHeightPane = new DualControlField<Double>("", "" , "", 2, 100, 1);
minMaxHeightPane.addChangeListener((obsval, oldval, newval)->{ minMaxHeightPane.addChangeListener((obsval, oldval, newval)->{
newSettings(); newSettings();
//do not allow the min ti be larger than the max. //do not allow the min ti be larger than the max.

View File

@ -901,13 +901,14 @@ public class TDGraphFX extends PamBorderPane {
} }
/** /**
* A tgool tip for detections. * A Tooltip for showing information about detections.
* *
* @author Jamie Macaulay * @author Jamie Macaulay
* *
*/ */
private class TDTooltip extends Tooltip { private class TDTooltip extends Tooltip {
private static final double TOOL_TIP_DELAY = 60; //seconds
private TDPlotPane plotPanel; private TDPlotPane plotPanel;
/** /**
@ -917,6 +918,8 @@ public class TDGraphFX extends PamBorderPane {
public TDTooltip(TDPlotPane aPlot) { public TDTooltip(TDPlotPane aPlot) {
super("Test tooltip"); super("Test tooltip");
this.plotPanel = aPlot; 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 * See https://bugs.openjdk.java.net/browse/JDK-8090477 fr info about tool tip
* timing on these displys. * timing on these displys.

View File

@ -19,7 +19,9 @@ import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import PamView.ColourArray.ColourArrayType;
import PamView.PamSymbol; import PamView.PamSymbol;
import PamView.PamView;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
import javafx.animation.KeyValue; import javafx.animation.KeyValue;
import javafx.animation.Timeline; import javafx.animation.Timeline;
@ -54,6 +56,13 @@ import pamViewFX.fxNodes.PamSymbolFX;
*/ */
public class PamUtilsFX { public class PamUtilsFX {
public static ColourArrayType fxColArray2Swing(pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType arrayFX) {
ColourArrayType type = ColourArrayType.valueOf(arrayFX.toString());
return type;
}
/** /**
* *
* @param awtColor * @param awtColor

View File

@ -19,7 +19,9 @@ import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
import rawDeepLearningClassifier.dlClassification.DLClassName; 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 { public class DLPredictionPane extends PamBorderPane implements TDSettingsPane {

View File

@ -1,10 +1,14 @@
package rawDeepLearningClassifier.dataPlotFX; package rawDeepLearningClassifier.dataPlotFX;
import java.awt.Color; import java.awt.Color;
import java.awt.event.ActionEvent;
import PamController.PamController;
import PamUtils.PamArrayUtils; import PamUtils.PamArrayUtils;
import PamView.GeneralProjector; import PamView.GeneralProjector;
import PamView.PamSymbolType; import PamView.PamSymbolType;
import PamView.dialog.GenericSwingDialog;
import PamView.dialog.PamDialogPanel;
import PamView.symbol.PamSymbolChooser; import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData; import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModType; import PamView.symbol.modifier.SymbolModType;
@ -21,8 +25,8 @@ import rawDeepLearningClassifier.logging.DLAnnotationType;
/** /**
* The DL symbol modifier. Colours symbols by eother the vlaue of the prediction by a user selected class * The DL symbol modifier. Colours symbols by either the value of the prediction
* or by the class with the highest prediction value. * by a user selected class or by the class with the highest prediction value.
* *
* @author Jamie Macaulay. * @author Jamie Macaulay.
* *
@ -38,12 +42,12 @@ public class DLSymbolModifier extends SymbolModifier {
/** /**
* The symbol options pane. * JavaFX symbol options pane.
*/ */
private DLSymbolOptionPane optionsPane; private DLSymbolOptionPane optionsPane;
/** /**
* Rge DL annotation type. * The DL annotation type.
*/ */
private DLAnnotationType dlAnnotType; private DLAnnotationType dlAnnotType;
@ -57,6 +61,11 @@ public class DLSymbolModifier extends SymbolModifier {
private ColourArray colourArray; private ColourArray colourArray;
/**
* Swing option panel for the symbol chooser.
*/
private DLSymbolOptionPanel optionsPanel;
public DLSymbolModifier(PamSymbolChooser symbolChooser, DLAnnotationType dlAnnotType) { 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. * Get the JavaFX symbol options pane that has options for the symbol pane.
* @return the symbol options pane. * @return the symbol options pane.
*/ */
@Override
public SymbolModifierPane getOptionsPane() { public SymbolModifierPane getOptionsPane() {
if (optionsPane == null) { if (optionsPane == null) {
optionsPane = new DLSymbolOptionPane(this); optionsPane = new DLSymbolOptionPane(this);
@ -233,6 +243,23 @@ public class DLSymbolModifier extends SymbolModifier {
return optionsPane; 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() { public DLAnnotationType getDLAnnotType() {
return dlAnnotType; return dlAnnotType;

View File

@ -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 { public class DLSymbolOptionPane extends StandardSymbolModifierPane {
@ -390,11 +392,11 @@ public class DLSymbolOptionPane extends StandardSymbolModifierPane {
// b1.setSelected(false); // b1.setSelected(false);
// b2.setSelected(false); // b2.setSelected(false);
if (symbolOptions.colTypeSelection == DLSymbolModifierParams.PREDICITON_COL) b1.setSelected(true); 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(); 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 //set the parameters for colouring by prediction
setPredictionColParams(symbolOptions); setPredictionColParams(symbolOptions);

View File

@ -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<String> classNameBox;
private JComboBox<String> 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<String> classNameBox) {
DLClassName[] classNames = dlSymbolModifier.getDLAnnotType().getDlControl().getDLModel().getClassNames();
// for (int i =0; i<classNames.length; i++) {
// System.out.println("DLSymbolOptionsPane: classNames: " + i + " " + classNames[i].className);
// }
int nClass = dlSymbolModifier.getDLAnnotType().getDlControl().getDLModel().getNumClasses();
classNameBox.removeAllItems();
for (int i=0; i<nClass; i++) {
if (classNames!=null && classNames.length>i) {
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<String>();
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();
}
}

View File

@ -65,7 +65,7 @@ public class DLPredictionFilter implements DLDataFilter {
} }
@Override @Override
public DataSelectParams getParams() { public DLPredictionFilterParams getParams() {
checkParamsClass() ; checkParamsClass() ;
return filterParams; return filterParams;
} }

View File

@ -1,34 +1,178 @@
package rawDeepLearningClassifier.dataSelector; 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.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.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamPanel;
import rawDeepLearningClassifier.dlClassification.DLClassName;
/** /**
* Swing panel for Deep learning predicitons. * Swing panel for Deep learning predicitons.
*/ */
public class DLPredictionPanel implements PamDialogPanel { public class DLPredictionPanel implements PamDialogPanel {
private DLPredictionFilter predicitonFilter;
private PamPanel contentPanel;
private JCheckBox[] enableClass;
private JSpinner[] spinnerClass;
private JToggleButton lockButton;
public DLPredictionPanel(DLPredictionFilter dlPredictionFilter) { public DLPredictionPanel(DLPredictionFilter dlPredictionFilter) {
super(); 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 @Override
public JComponent getDialogComponent() { public JComponent getDialogComponent() {
// TODO Auto-generated method stub return contentPanel;
return null;
} }
@Override @Override
public void setParams() { public void setParams() {
// TODO Auto-generated method stub
DLPredictionFilterParams params = predicitonFilter.getParams();
// TODO Auto-generated method stub
setClassPane(params);
for (int i=0; i<params.classSelect.length ; i++) {
//set the correct params
enableClass[i].setSelected(params.classSelect[i]);
spinnerClass[i].setValue(params.minClassPredicton[i]);
}
}
private void setClassPane(DLPredictionFilterParams input) {
DLClassName[] classNames = predicitonFilter.getDLControl().getDLModel().getClassNames();
contentPanel.removeAll();
enableClass = new JCheckBox[input.classSelect.length];
spinnerClass = new JSpinner[input.classSelect.length];
GridBagConstraints c = new PamGridBagContraints();
c.ipadx =5;
for (int i=0; i<input.classSelect.length ; i++) {
//create the row
c.gridx = 0;
enableClass[i] = new JCheckBox(classNames[i].className);
final int ii = i;
enableClass[i].addActionListener((action)->{
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; j<spinnerClass.length ; j++) {
if (j!=ii) {
spinnerClass[j].setValue(spinnerClass[ii].getValue());
}
}
}
}
});
spinnerClass[i].setToolTipText(classNames[i].className);
contentPanel.add(spinnerClass[i], c);
if (i==0 && input.classSelect.length>1) {
//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 @Override
public boolean getParams() { public boolean getParams() {
// TODO Auto-generated method stub
return false; DLPredictionFilterParams currParams = predicitonFilter.getParams();
for (int i=0; i<spinnerClass.length ; i++) {
currParams.classSelect[i] = enableClass[i].isSelected();
currParams.minClassPredicton[i] = (double) spinnerClass[i].getValue();
}
predicitonFilter.setParams(currParams);
return true;
} }
} }

View File

@ -9,14 +9,11 @@ import javafx.scene.control.Slider;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import javafx.scene.text.TextAlignment;
import pamViewFX.PamGuiManagerFX; import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude; import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane; import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamHBox; import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamVBox; import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.sliders.PamSlider;
import pamViewFX.fxSettingsPanes.DynamicSettingsPane; import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
import rawDeepLearningClassifier.dlClassification.DLClassName; import rawDeepLearningClassifier.dlClassification.DLClassName;
@ -47,7 +44,7 @@ public class DLPredictonPane extends DynamicSettingsPane<DLPredictionFilterParam
PamBorderPane topPane = new PamBorderPane(); PamBorderPane topPane = new PamBorderPane();
Label label = new Label("Select classes to show"); Label label = new Label("Show classes above min. prediction");
PamBorderPane.setAlignment(label, Pos.BOTTOM_LEFT); PamBorderPane.setAlignment(label, Pos.BOTTOM_LEFT);
// label.setTextAlignment(TextAlignment.LEFT); // label.setTextAlignment(TextAlignment.LEFT);
label.setAlignment(Pos.BOTTOM_LEFT); label.setAlignment(Pos.BOTTOM_LEFT);
@ -87,6 +84,8 @@ public class DLPredictonPane extends DynamicSettingsPane<DLPredictionFilterParam
Label valueLabel; Label valueLabel;
private boolean enableListener = true;
ClassDataSelector(String classType, int index) { ClassDataSelector(String classType, int index) {
enable = new CheckBox(classType); enable = new CheckBox(classType);
@ -110,10 +109,13 @@ public class DLPredictonPane extends DynamicSettingsPane<DLPredictionFilterParam
//if the lock button has been sleected then change all the sliders //if the lock button has been sleected then change all the sliders
//so that they are the same value as this slide (unless the class is disabled) //so that they are the same value as this slide (unless the class is disabled)
if (toggelButton.isSelected()) { if (toggelButton.isSelected() && enableListener) {
for (int i=0; i<classPanes.length; i++) { for (int i=0; i<classPanes.length; i++) {
if (classPanes[i].enable.isSelected() && i!=index) { if (classPanes[i].enable.isSelected() && i!=index) {
classPanes[i].enableListener = false; //prevent needless calls to notify settings
classPanes[i].slider.setValue(newval.doubleValue()); classPanes[i].slider.setValue(newval.doubleValue());
classPanes[i].enableListener = true;
} }
}; };
} }

View File

@ -1,35 +1,78 @@
package rawDeepLearningClassifier.dataSelector; package rawDeepLearningClassifier.dataSelector;
import java.awt.BorderLayout;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import PamView.dialog.PamDialogPanel; import PamView.dialog.PamDialogPanel;
import PamView.panel.PamPanel;
import javafx.scene.Node;
import pamViewFX.fxNodes.PamBorderPane;
/** /**
* Swing panel for the deep learning data selector. * Swing panel for the deep learning data selector.
*/ */
public class DLSelectPanel implements PamDialogPanel { public class DLSelectPanel implements PamDialogPanel {
private PamPanel mainPanel;
private DLDataSelector dlDataSelector;
private int currentIndex = 0;
public DLSelectPanel(DLDataSelector dlDataSelector) { public DLSelectPanel(DLDataSelector dlDataSelector) {
// TODO Auto-generated constructor stub super();
this.dlDataSelector=dlDataSelector;
mainPanel = new PamPanel();
mainPanel.setLayout(new BorderLayout());
} }
@Override @Override
public JComponent getDialogComponent() { public JComponent getDialogComponent() {
// TODO Auto-generated method stub return mainPanel;
return new JLabel("Hello Annotation DL"); }
private void setDataFilterPane(int index) {
DLDataFilter dlFilter = dlDataSelector.getDataSelectors().get(index);
mainPanel.add(dlFilter.getSettingsPanel().getDialogComponent(), BorderLayout.CENTER);
} }
@Override @Override
public void setParams() { public void setParams() {
// TODO Auto-generated method stub DLDataSelectorParams currParams = dlDataSelector.getParams();
this.currentIndex = currParams.dataSelectorIndex;
//set the stored paramters for the deep learning filter
dlDataSelector.getDataSelectors().get(currentIndex).setParams(currParams.dataSelectorParams[currentIndex]);
//set the paramters in the dialog - note the dialog will have areference ot the filter and so can access the r
//set params above.
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPanel().setParams();
//set the
setDataFilterPane(currentIndex);
} }
@Override @Override
public boolean getParams() { public boolean getParams() {
// TODO Auto-generated method stub
DLDataSelectorParams currParams = dlDataSelector.getParams();
//dialog has a reference to the data filter and will change params.
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPanel().getParams();
//TODO - maybe should grab settings from all filters or just the selected one?
currParams.dataSelectorParams[currentIndex] = dlDataSelector.getDataSelectors().get(currentIndex).getParams();
dlDataSelector.setParams(currParams);
return true; return true;
} }
} }