Commit 8e1e2367 authored by Jaroslav Plšek's avatar Jaroslav Plšek Committed by Radek Ošlejšek
Browse files

Resolve "Refactoring: Management of feature points"

parent a45e0d39
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import java.util.List;
 * @author Radek Oslejsek
 * @author Matej Kovar
 * @author Katerina Zarska
 * @author Jaroslav Plsek
 */
public interface HumanFace extends Serializable {

@@ -85,17 +86,18 @@ public interface HumanFace extends Serializable {
    List<Landmark> getCustomLandmarks();

    /**
     * Adds custom landmark to face
     * Adds all types of {@link Landmark} (including standard or custom) to the face if they are not already present.
     * @param landmark {@link Landmark} to add
     * @return {@code true} if the landmark was added, {@code false} otherwise
     */
    void addCustomLandmark(Landmark landmark);
    boolean addLandmark(Landmark landmark);

    /**
     * Removes custom landmark from face
     *
     * Removes any type of {@link Landmark} from the face.
     * @param landmark Landmark to remove
     * @return true if the landmark was removed, false otherwise
     */
    boolean removeCustomLandmark(Landmark landmark);
    boolean removeLandmark(Landmark landmark);

    /**
     * Checks if HumanFace has feature points
@@ -104,6 +106,13 @@ public interface HumanFace extends Serializable {
     */
    boolean hasLandmarks();

    /**
     * Generates a new unique ID for a user-defined landmark.
     * The ID series for <b>user-defined landmarks</b> starts from <b>{@code ID 501}</b>.
     * @return a new unique ID for a user-defined landmark
     */
    int getNextUserLandmarkId();

    /**
     * Returns short name of the face without its path in the name. May not be unique.
     *
+17 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import java.util.Objects;
 * @author Radek Oslejsek
 * @author Matej Kovar
 * @author Katerina Zarska
 * @author Jaroslav Plsek
 */
public class HumanFaceImpl implements HumanFace {

@@ -174,20 +175,25 @@ public class HumanFaceImpl implements HumanFace {
    }

    @Override
    public void addCustomLandmark(Landmark landmark) {
    public boolean addLandmark(Landmark landmark) {
        if (landmark == null) {
            return;
            return false;
        }

        if (featurePoints == null) {
            featurePoints = new ArrayList<>();
        }

        if (featurePoints.contains(landmark)) {
            return false;
        }

        featurePoints.add(landmark);
        return true;
    }

    @Override
    public boolean removeCustomLandmark(Landmark landmark) {
    public boolean removeLandmark(Landmark landmark) {
        if (landmark == null || featurePoints == null) {
            return false;
        }
@@ -201,6 +207,14 @@ public class HumanFaceImpl implements HumanFace {
    }

    @Override
    public int getNextUserLandmarkId() {
        var featurePoints = getCustomLandmarks();
        return featurePoints.isEmpty() ? 501 : featurePoints.stream()
                .map(Landmark::getType)
                .max(Integer::compareTo)
                .orElse(500) + 1;
    }

    public String getShortName() {
        return name;
    }
+18 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import java.util.Objects;
 *
 * @param <T> content of a row
 * @author Radek Oslejsek
 * @author Jaroslav Plsek
 */
public abstract class FpListAbstractPanel<T extends FpListAbstractPanel.Row> extends JPanel {

@@ -162,4 +163,21 @@ public abstract class FpListAbstractPanel<T extends FpListAbstractPanel.Row> ext
        }
    }

    /**
     * Enables or disables all checkboxes in the list.
     *
     * @param enabled true to enable, false to disable
     */
    public void setEnabledCheckboxes(boolean enabled) {
        rows.forEach(row -> row.getCheckbox().setEnabled(enabled));
    }

    /**
     * Selects or deselects all checkboxes in the list.
     * @param selected true to select, false to deselect
     */
    public void setSelectedAllCheckboxes(boolean selected) {
        rows.forEach(row -> row.getCheckbox().setSelected(selected));
    }

}
+0 −176
Original line number Diff line number Diff line
package cz.fidentis.analyst.gui.task.featurepoints;

import cz.fidentis.analyst.data.landmarks.Landmark;
import cz.fidentis.analyst.data.landmarks.MeshVicinity;
import cz.fidentis.analyst.drawables.DrawableFeaturePoints;
import cz.fidentis.analyst.gui.task.LoadedActionEvent;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Katerina Zarska
 */
public class FeaturePointListPanel extends JPanel {
    
    public static final String ACTION_COMMAND_FEATURE_POINT_HOVER_IN = "highlight hovered FP";
    public static final String ACTION_COMMAND_FEATURE_POINT_HOVER_OUT = "set default color of hovered FP";
    public static final String ACTION_COMMAND_FEATURE_POINT_SELECT = "highlight feature point with color";
    
    private List<JLabel> colorIndicators;
    private List<JCheckBox> featurePointCheckBoxes;
    
    /**
     * Constructor.
     * 
     * @param action Action listener
     * @param featurePoints List of all feature points 
     */
    public void initComponents(ActionListener action, DrawableFeaturePoints featurePoints) {
        setLayout(new GridBagLayout());
        
        featurePointCheckBoxes = new ArrayList<>(featurePoints.getFeaturePoints().size());
        colorIndicators = new ArrayList<>(featurePoints.getFeaturePoints().size());
        
        for (int i = 0; i < featurePoints.getFeaturePoints().size(); i++) {
            addRow(i, action, featurePoints);
        }
    }
    
    /**
     * (De)selects given feature point
     * 
     * @param index Index of the feature point
     * @param selected {@code true} if a feature point checkbox is to be selected,
     *                 {@code false} otherwise
     */
    public void selectFeaturePoint(int index, boolean selected) {
        if (index >= 0 && index < featurePointCheckBoxes.size()) {
            featurePointCheckBoxes.get(index).setSelected(selected);
        }
    }
    
    /**
     * Refreshes the panel
     * @param action
     * @param featurePoints 
     */
    public void refreshPanel(ActionListener action, DrawableFeaturePoints featurePoints, List<Landmark> selectedFeaturePoints) {
        removeAll();
        initComponents(action, featurePoints);
        revalidate();
        repaint();

        for (int i = 0; i < featurePoints.getFeaturePoints().size(); i++) {
            if (selectedFeaturePoints.contains(featurePoints.getFeaturePoints().get(i))) {
                featurePointCheckBoxes.get(i).setSelected(true);
            } else {
                featurePointCheckBoxes.get(i).setSelected(false);
            }
        }
    }
    
    /**
     * Creates and returns action listener that can be connected with a low-level 
     * GUI element (e.g., a button). Action event of triggered low-level element is
     * redirected to the given {@code action}.
     * The listener may also carry additional data as a payload.
     * 
     * @param action Action listener
     * @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
            public void actionPerformed(ActionEvent e) {
                action.actionPerformed(new LoadedActionEvent(
                        e.getSource(), 
                        ActionEvent.ACTION_PERFORMED, 
                        command,
                        data)
                ); 
            }  
        };
    }
    
    protected void addRow(int row, ActionListener action, DrawableFeaturePoints featurePoints) {
        Landmark featurePoint = featurePoints.getFeaturePoints().get(row);
        
        Color color = featurePoints.getOffTheMeshColor();
        MeshVicinity.Location fpType = featurePoint.getMeshVicinity().getPositionType(featurePoints.getDistanceThreshold());
        if (featurePoint.isUserDefinedLandmark()) {
            color = featurePoints.getCustomFpColor();
        } else if (fpType == MeshVicinity.Location.ON_THE_MESH) {
            color = featurePoints.getOnTheMeshColor();
        } else if (fpType == MeshVicinity.Location.CLOSE_TO_MESH) {
            color = featurePoints.getCloseToMeshColor();
        }

        GridBagConstraints c = new GridBagConstraints();  
        c.gridwidth = 1;
        c.gridx = 0;
        c.gridy = row;
        c.anchor = GridBagConstraints.LINE_START;
        c.fill = GridBagConstraints.NONE;
        
        GridBagConstraints c1 = new GridBagConstraints();
        c1.insets = new Insets(0, 10, 0, 10);
        c1.gridwidth = GridBagConstraints.REMAINDER;
        c1.gridx = 1;
        c1.gridy = row;
        c1.anchor = GridBagConstraints.LINE_END;
        c1.fill = GridBagConstraints.NONE; 
        
        //adds a color indicator to the end of the line to show the relation to mesh of the feature point
        JLabel colorIndicator = new JLabel("");
        Border border = BorderFactory.createLineBorder(Color.GRAY, 1);
        colorIndicator.setOpaque(true);
        colorIndicator.setBackground(color);
        colorIndicator.setForeground(Color.GRAY);
        colorIndicator.setBorder(border);
        Dimension d = new Dimension(10, 10);
        colorIndicator.setMinimumSize(d);
        colorIndicator.setMaximumSize(d);
        colorIndicator.setPreferredSize(d);
        add(colorIndicator, c1);
        colorIndicators.add(colorIndicator);
        
        //adds a checkbox with the name of the feature point
        JCheckBox checkBox = new JCheckBox();
        checkBox.setText(featurePoint.getName());
        add(checkBox, c);
        featurePointCheckBoxes.add(checkBox);
        
        checkBox.addActionListener(createListener(action, ACTION_COMMAND_FEATURE_POINT_SELECT, row));
        
        final int index = row;
        checkBox.addMouseListener(new MouseAdapter() { // highlight spheres on mouse hover
            @Override
            public void mouseEntered(MouseEvent e) {
                action.actionPerformed(new LoadedActionEvent(
                        e.getSource(),
                        ActionEvent.ACTION_PERFORMED,
                        ACTION_COMMAND_FEATURE_POINT_HOVER_IN,
                        index));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                action.actionPerformed(new LoadedActionEvent(
                        e.getSource(),
                        ActionEvent.ACTION_PERFORMED,
                        ACTION_COMMAND_FEATURE_POINT_HOVER_OUT,
                        index));
            }
        });
    }
}
+158 −88

File changed.

Preview size limit exceeded, changes collapsed.

Loading