Loading Comparison/src/main/java/cz/fidentis/analyst/visitors/face/HausdorffDistancePrioritized.java +7 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,13 @@ public class HausdorffDistancePrioritized extends HumanFaceVisitor { } } /** * Finds and returns a feature point of the desired type in the given human face. * * @param face Face containing the desired feature point * @param type Type of the feature point to be obtained * @return Feature point of the desired type */ protected FeaturePoint getFeaturePointByType(HumanFace face, FeaturePointType type) { for (final FeaturePoint featurePoint: face.getFeaturePoints()) { if (type.getType() == featurePoint.getFeaturePointType().getType()) { Loading GUI/src/main/java/cz/fidentis/analyst/core/ControlPanel.java +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,17 @@ public abstract class ControlPanel extends JPanel { }; } /** * Creates and returns action listener that can be connected with a low-level * GUI element (e.g., a button). Action event of the low-level element is then * re-directed to the given {@code ControlPanelAction} as given command. * The listener may also carry additional data as a payload. * * @param action An instance of the {@link ControlPanelAction} * @param command Control panel command * @param data Payload data of the action listener * @return Action listener */ protected final ActionListener createListener(ActionListener action, String command, Object data) { return new AbstractAction() { @Override Loading GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelBuilder.java +40 −5 Original line number Diff line number Diff line Loading @@ -137,18 +137,32 @@ public class ControlPanelBuilder { return label; } public JLabel addLabelLine(String caption) { return addLabelLineCustom(caption, new GridBagConstraints()); /** * Adds a line with a plain text label. * * @param text Text of the label * @return This new GUI object */ public JLabel addLabelLine(String text) { return addLabelLineCustom(text, new GridBagConstraints()); } private JLabel addLabelLineCustom(String caption, GridBagConstraints constraints) { /** * Adds a line with a plain text label whose appearance can be further * customized by {@code constraints}. * * @param text Text of the label * @param constraints {@code GridBagConstraints} to customize the label * @return This new GUI object */ private JLabel addLabelLineCustom(String text, GridBagConstraints constraints) { constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.gridx = col; constraints.gridy = row; constraints.anchor = GridBagConstraints.LINE_START; constraints.fill = GridBagConstraints.NONE; JLabel label = new JLabel(caption); JLabel label = new JLabel(text); controlPanel.add(label, constraints); return label; Loading Loading @@ -258,10 +272,25 @@ public class ControlPanelBuilder { return retButtons; } /** * Adds a simple button. * * @param caption Label * @param action Action listener invoked when the corresponding button is clicked * @return This new GUI object */ public JButton addButton(String caption, ActionListener action) { return addButtonCustom(caption, action, new GridBagConstraints()); } /** * Adds a simple button whose appearance can be further customized by {@code constraints}. * * @param caption Label * @param action Action listener invoked when the corresponding button is clicked * @param constraints {@code GridBagConstraints} to customize the button * @return This new GUI object */ private JButton addButtonCustom(String caption, ActionListener action, GridBagConstraints constraints) { JButton button = new JButton(); button.setText(caption); Loading Loading @@ -454,6 +483,12 @@ public class ControlPanelBuilder { return slider; } /** * Adds a scrollable pane that carries the given panel as its content. * * @param content Panel to be made scrollable * @return This new GUI object */ public JScrollPane addScrollPane(JPanel content) { JScrollPane scrollPane = new JScrollPane(content); Loading GUI/src/main/java/cz/fidentis/analyst/core/LoadedActionEvent.java +51 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package cz.fidentis.analyst.core; import java.awt.event.ActionEvent; /** * A subclass of {@link ActionEvent} extended to carry additional data as a payload. * * @author Daniel Schramm */ Loading @@ -10,21 +11,70 @@ public class LoadedActionEvent extends ActionEvent { private final Object data; /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, Object data) { super(source, id, command); this.data = data; } /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param modifiers The modifier keys down during event (shift, ctrl, alt, meta). * Passing negative parameter is not recommended. * Zero value means that no modifiers were passed * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, int modifiers, Object data) { super(source, id, command, modifiers); this.data = data; } /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param modifiers The modifier keys down during event (shift, ctrl, alt, meta). * Passing negative parameter is not recommended. * Zero value means that no modifiers were passed * @param when A long that gives the time the event occurred. * Passing negative or zero value is not recommended * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, long when, int modifiers, Object data) { super(source, id, command, when, modifiers); this.data = data; } /** * Returns payload data of the action event. * * @return Payload data of the action event */ public Object getData() { return data; } Loading GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java +39 −5 Original line number Diff line number Diff line Loading @@ -101,6 +101,10 @@ public class DistanceAction extends ControlPanelAction { renderScene(); } /** * (Re)calculates the Hausdorff distance and updates the heat map of the secondary face * as well as values of all appropriate GUI elements of {@link DistancePanel}. */ protected void calculateHausdorffDistance() { final Strategy useStrategy; switch (strategy) { Loading @@ -124,16 +128,21 @@ public class DistanceAction extends ControlPanelAction { hausdorffDistance = null; } // Update GUI elements that display the calculated Hausdorff distance if (hausdorffDistance == null) { hausdorffDistance = getPrioritizedDistance(); hausdorffDistance = getWeightedDistance(); setHausdorffDistanceStatistics(); setFeaturePointWeigths(); } getSecondaryDrawableFace().setHeatMap(hausdorffDistance); } private Map<MeshFacet, List<Double>> getPrioritizedDistance() { /** * Calculates weighted (or regular) Hausdorff distance of the face. * * @return weighted Hausdorff distance */ private Map<MeshFacet, List<Double>> getWeightedDistance() { if (!weightedDist) { return visitor.getDistances(); } Loading @@ -151,13 +160,16 @@ public class DistanceAction extends ControlPanelAction { IntStream.range(0, distancesList.size()) .mapToDouble(i -> distancesList.get(i) * prioritiesList.get(i)) .boxed() .collect(Collectors.toList()) ); .collect(Collectors.toList())); } return weightedDistances; } /** * Updates the GUI elements of {@link DistancePanel} elements that display * statistical data about the calculated Hausdorff distance. */ private void setHausdorffDistanceStatistics() { final DoubleSummaryStatistics distanceStats = hausdorffDistance.values() .stream() Loading @@ -172,6 +184,10 @@ public class DistanceAction extends ControlPanelAction { ); } /** * Updates the GUI elements of {@link DistancePanel} that display * the weights of feature points used to calculate the weighted Hausdorff distance. */ private void setFeaturePointWeigths() { if (!weightedDist) { controlPanel.updateFeaturePointWeights(Map.of()); Loading @@ -194,6 +210,12 @@ public class DistanceAction extends ControlPanelAction { .orElse(Double.NaN)))); } /** * Changes the colour of the secondary face's feature point at the given index. * The index is received as the data payload of {@code actionEvent}. * * @param actionEvent Action event with the index of the feature point as its payload data */ private void highlightFeaturePoint(LoadedActionEvent actionEvent) { final int index = (int) actionEvent.getData(); final FeaturePointType fpType = getTypeOfFeaturePoint(index); Loading @@ -208,6 +230,12 @@ public class DistanceAction extends ControlPanelAction { } } /** * Changes the size of the secondary face's feature point at the given index. * The index is received as the data payload of {@code actionEvent}. * * @param actionEvent Action event with the index of the feature point as its payload data */ private void resizeFeaturePoint(LoadedActionEvent actionEvent) { final int index = (int) actionEvent.getData(); final double size = Double.parseDouble(((JTextField) actionEvent.getSource()).getText()); Loading @@ -216,6 +244,12 @@ public class DistanceAction extends ControlPanelAction { featurePointTypes.replace(getTypeOfFeaturePoint(index), size); } /** * Returns type of the feature point at the given index in the secondary face. * * @param index Index of the feature point * @return Type of the feature point or {@code null} */ private FeaturePointType getTypeOfFeaturePoint(int index) { final List<FeaturePoint> featurePoints = getSecondaryFeaturePoints().getFeaturePoints(); if (index < 0 || index >= featurePoints.size()) { Loading Loading
Comparison/src/main/java/cz/fidentis/analyst/visitors/face/HausdorffDistancePrioritized.java +7 −0 Original line number Diff line number Diff line Loading @@ -401,6 +401,13 @@ public class HausdorffDistancePrioritized extends HumanFaceVisitor { } } /** * Finds and returns a feature point of the desired type in the given human face. * * @param face Face containing the desired feature point * @param type Type of the feature point to be obtained * @return Feature point of the desired type */ protected FeaturePoint getFeaturePointByType(HumanFace face, FeaturePointType type) { for (final FeaturePoint featurePoint: face.getFeaturePoints()) { if (type.getType() == featurePoint.getFeaturePointType().getType()) { Loading
GUI/src/main/java/cz/fidentis/analyst/core/ControlPanel.java +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,17 @@ public abstract class ControlPanel extends JPanel { }; } /** * Creates and returns action listener that can be connected with a low-level * GUI element (e.g., a button). Action event of the low-level element is then * re-directed to the given {@code ControlPanelAction} as given command. * The listener may also carry additional data as a payload. * * @param action An instance of the {@link ControlPanelAction} * @param command Control panel command * @param data Payload data of the action listener * @return Action listener */ protected final ActionListener createListener(ActionListener action, String command, Object data) { return new AbstractAction() { @Override Loading
GUI/src/main/java/cz/fidentis/analyst/core/ControlPanelBuilder.java +40 −5 Original line number Diff line number Diff line Loading @@ -137,18 +137,32 @@ public class ControlPanelBuilder { return label; } public JLabel addLabelLine(String caption) { return addLabelLineCustom(caption, new GridBagConstraints()); /** * Adds a line with a plain text label. * * @param text Text of the label * @return This new GUI object */ public JLabel addLabelLine(String text) { return addLabelLineCustom(text, new GridBagConstraints()); } private JLabel addLabelLineCustom(String caption, GridBagConstraints constraints) { /** * Adds a line with a plain text label whose appearance can be further * customized by {@code constraints}. * * @param text Text of the label * @param constraints {@code GridBagConstraints} to customize the label * @return This new GUI object */ private JLabel addLabelLineCustom(String text, GridBagConstraints constraints) { constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.gridx = col; constraints.gridy = row; constraints.anchor = GridBagConstraints.LINE_START; constraints.fill = GridBagConstraints.NONE; JLabel label = new JLabel(caption); JLabel label = new JLabel(text); controlPanel.add(label, constraints); return label; Loading Loading @@ -258,10 +272,25 @@ public class ControlPanelBuilder { return retButtons; } /** * Adds a simple button. * * @param caption Label * @param action Action listener invoked when the corresponding button is clicked * @return This new GUI object */ public JButton addButton(String caption, ActionListener action) { return addButtonCustom(caption, action, new GridBagConstraints()); } /** * Adds a simple button whose appearance can be further customized by {@code constraints}. * * @param caption Label * @param action Action listener invoked when the corresponding button is clicked * @param constraints {@code GridBagConstraints} to customize the button * @return This new GUI object */ private JButton addButtonCustom(String caption, ActionListener action, GridBagConstraints constraints) { JButton button = new JButton(); button.setText(caption); Loading Loading @@ -454,6 +483,12 @@ public class ControlPanelBuilder { return slider; } /** * Adds a scrollable pane that carries the given panel as its content. * * @param content Panel to be made scrollable * @return This new GUI object */ public JScrollPane addScrollPane(JPanel content) { JScrollPane scrollPane = new JScrollPane(content); Loading
GUI/src/main/java/cz/fidentis/analyst/core/LoadedActionEvent.java +51 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ package cz.fidentis.analyst.core; import java.awt.event.ActionEvent; /** * A subclass of {@link ActionEvent} extended to carry additional data as a payload. * * @author Daniel Schramm */ Loading @@ -10,21 +11,70 @@ public class LoadedActionEvent extends ActionEvent { private final Object data; /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, Object data) { super(source, id, command); this.data = data; } /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param modifiers The modifier keys down during event (shift, ctrl, alt, meta). * Passing negative parameter is not recommended. * Zero value means that no modifiers were passed * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, int modifiers, Object data) { super(source, id, command, modifiers); this.data = data; } /** * Constructor. * * @param source The object that originated the event * @param id An integer that identifies the event. * For information on allowable values, see the class description * for {@link ActionEvent} * @param command A string that may specify a command (possibly one * of several) associated with the event * @param modifiers The modifier keys down during event (shift, ctrl, alt, meta). * Passing negative parameter is not recommended. * Zero value means that no modifiers were passed * @param when A long that gives the time the event occurred. * Passing negative or zero value is not recommended * @param data Payload data of the event * @throws IllegalArgumentException if {@code source} is null */ public LoadedActionEvent(Object source, int id, String command, long when, int modifiers, Object data) { super(source, id, command, when, modifiers); this.data = data; } /** * Returns payload data of the action event. * * @return Payload data of the action event */ public Object getData() { return data; } Loading
GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java +39 −5 Original line number Diff line number Diff line Loading @@ -101,6 +101,10 @@ public class DistanceAction extends ControlPanelAction { renderScene(); } /** * (Re)calculates the Hausdorff distance and updates the heat map of the secondary face * as well as values of all appropriate GUI elements of {@link DistancePanel}. */ protected void calculateHausdorffDistance() { final Strategy useStrategy; switch (strategy) { Loading @@ -124,16 +128,21 @@ public class DistanceAction extends ControlPanelAction { hausdorffDistance = null; } // Update GUI elements that display the calculated Hausdorff distance if (hausdorffDistance == null) { hausdorffDistance = getPrioritizedDistance(); hausdorffDistance = getWeightedDistance(); setHausdorffDistanceStatistics(); setFeaturePointWeigths(); } getSecondaryDrawableFace().setHeatMap(hausdorffDistance); } private Map<MeshFacet, List<Double>> getPrioritizedDistance() { /** * Calculates weighted (or regular) Hausdorff distance of the face. * * @return weighted Hausdorff distance */ private Map<MeshFacet, List<Double>> getWeightedDistance() { if (!weightedDist) { return visitor.getDistances(); } Loading @@ -151,13 +160,16 @@ public class DistanceAction extends ControlPanelAction { IntStream.range(0, distancesList.size()) .mapToDouble(i -> distancesList.get(i) * prioritiesList.get(i)) .boxed() .collect(Collectors.toList()) ); .collect(Collectors.toList())); } return weightedDistances; } /** * Updates the GUI elements of {@link DistancePanel} elements that display * statistical data about the calculated Hausdorff distance. */ private void setHausdorffDistanceStatistics() { final DoubleSummaryStatistics distanceStats = hausdorffDistance.values() .stream() Loading @@ -172,6 +184,10 @@ public class DistanceAction extends ControlPanelAction { ); } /** * Updates the GUI elements of {@link DistancePanel} that display * the weights of feature points used to calculate the weighted Hausdorff distance. */ private void setFeaturePointWeigths() { if (!weightedDist) { controlPanel.updateFeaturePointWeights(Map.of()); Loading @@ -194,6 +210,12 @@ public class DistanceAction extends ControlPanelAction { .orElse(Double.NaN)))); } /** * Changes the colour of the secondary face's feature point at the given index. * The index is received as the data payload of {@code actionEvent}. * * @param actionEvent Action event with the index of the feature point as its payload data */ private void highlightFeaturePoint(LoadedActionEvent actionEvent) { final int index = (int) actionEvent.getData(); final FeaturePointType fpType = getTypeOfFeaturePoint(index); Loading @@ -208,6 +230,12 @@ public class DistanceAction extends ControlPanelAction { } } /** * Changes the size of the secondary face's feature point at the given index. * The index is received as the data payload of {@code actionEvent}. * * @param actionEvent Action event with the index of the feature point as its payload data */ private void resizeFeaturePoint(LoadedActionEvent actionEvent) { final int index = (int) actionEvent.getData(); final double size = Double.parseDouble(((JTextField) actionEvent.getSource()).getText()); Loading @@ -216,6 +244,12 @@ public class DistanceAction extends ControlPanelAction { featurePointTypes.replace(getTypeOfFeaturePoint(index), size); } /** * Returns type of the feature point at the given index in the secondary face. * * @param index Index of the feature point * @return Type of the feature point or {@code null} */ private FeaturePointType getTypeOfFeaturePoint(int index) { final List<FeaturePoint> featurePoints = getSecondaryFeaturePoints().getFeaturePoints(); if (index < 0 || index >= featurePoints.size()) { Loading