diff --git a/Comparison/src/main/java/cz/fidentis/analyst/Project.java b/Comparison/src/main/java/cz/fidentis/analyst/Project.java index 3b891f298ecb835717f646a7d708723fcb2e6d7c..33f3eccc4eb77a8afeb8216b2f2122db6fddec8f 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/Project.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/Project.java @@ -110,5 +110,35 @@ public class Project { } return null; } + + /** + * Checks whether model saved in this project has in the same directory + * file with feature points + * @param name String name of face + * @return true if feature points file was found, false otherwise + */ + public boolean hasFPByName(String name) { + + Path path = this.getCfg().getPathToFaceByName(name); + + if (path != null) { + + String filePath = path.toString().split(".obj")[0] + "_landmarks.csv"; + if ((new File(filePath)).exists()) { + return true; + } + + filePath = path.toString().split("_ECA")[0] + "_landmarks.csv"; + if ((new File(filePath)).exists()) { + return true; + } + + filePath = path.toString().split("_CA")[0] + "_landmarks.csv"; + if ((new File(filePath)).exists()) { + return true; + } + } + return false; + } } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java index c9e9e711f60c7849684c0066d52248970d64c5e4..dc8f0cbe0c799305dc90e5295aa1fab8a543756c 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java @@ -64,7 +64,7 @@ public class ProjectConfiguration { * @param name String name of file * @return Path to face */ - public Path getPathToFaceByName(String name) { + public Path getPathToFaceByName(String name) { for (Path p : paths) { if (p.toString().substring(p.toString().lastIndexOf(File.separatorChar) + 1, p.toString().lastIndexOf('.')).equals(name)) { return p; diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceGeometryInfo.java b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceGeometryInfo.java similarity index 96% rename from GUI/src/main/java/cz/fidentis/analyst/project/FaceGeometryInfo.java rename to GUI/src/main/java/cz/fidentis/analyst/faceState/FaceGeometryInfo.java index ab96418181ca0352669a0daa8133dbc07746824c..4de1b2b436ea87645b75ef19dde8fd703b161850 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FaceGeometryInfo.java +++ b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceGeometryInfo.java @@ -1,4 +1,4 @@ -package cz.fidentis.analyst.project; +package cz.fidentis.analyst.faceState; import java.util.List; diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.form similarity index 84% rename from GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form rename to GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.form index 100b4d23178652ad8205a1bad5cf8746192acdc0..48a9fceae54b7be96ce5c6e9e9857d4e1b11ec0d 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form +++ b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.form @@ -47,7 +47,7 @@ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> <TitledBorder title="File info"> - <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.filePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.filePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> <Font PropertyName="font" name="Dialog" size="14" style="1"/> </TitledBorder> </Border> @@ -55,7 +55,7 @@ </Properties> <AccessibilityProperties> <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.filePanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.filePanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </AccessibilityProperties> @@ -125,7 +125,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -133,7 +133,7 @@ <Component class="javax.swing.JLabel" name="pathOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.pathOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.pathOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -143,7 +143,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -151,7 +151,7 @@ <Component class="javax.swing.JLabel" name="sizeOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.sizeOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.sizeOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -161,7 +161,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.featurePointsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.featurePointsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -169,7 +169,7 @@ <Component class="javax.swing.JLabel" name="featurePointsOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.featurePointsOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.featurePointsOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -179,7 +179,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.previewLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.previewLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -187,7 +187,7 @@ <Component class="javax.swing.JLabel" name="previewOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.previewOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.previewOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -197,7 +197,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.textureLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.textureLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -205,7 +205,7 @@ <Component class="javax.swing.JLabel" name="textureOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.textureOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.textureOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -216,7 +216,7 @@ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> <TitledBorder title="Geometry info"> - <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.geometryPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.geometryPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> <Font PropertyName="font" name="Dialog" size="14" style="1"/> </TitledBorder> </Border> @@ -291,7 +291,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.verticesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.verticesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -299,7 +299,7 @@ <Component class="javax.swing.JLabel" name="verticesOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.verticesOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.verticesOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -309,7 +309,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.facetsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.facetsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -317,7 +317,7 @@ <Component class="javax.swing.JLabel" name="facetsOutput"> <Properties> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.facetsOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.facetsOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -327,7 +327,7 @@ <Font name="Tahoma" size="10" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.fpLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.fpLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="enabled" type="boolean" value="false"/> </Properties> @@ -348,7 +348,7 @@ <Font name="Tahoma" size="12" style="1"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.loadInfoButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.loadInfoButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> </Component> @@ -359,7 +359,7 @@ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> <TitledBorder title="Photo"> - <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.photoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.photoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> <Font PropertyName="font" name="Dialog" size="14" style="1"/> </TitledBorder> </Border> @@ -393,7 +393,7 @@ <Image iconType="3" name="/face160x160.png"/> </Property> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.photo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <ResourceString bundle="cz/fidentis/analyst/faceState/Bundle.properties" key="FaceStatePanel.photo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> <Events> diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.java similarity index 98% rename from GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java rename to GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.java index 1fbddaa3f169c63112985fe7ee23f32e9f8bda5b..c1e3376e3a1c7b203322a1615c85d11014155917 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/faceState/FaceStatePanel.java @@ -1,11 +1,11 @@ -package cz.fidentis.analyst.project; +package cz.fidentis.analyst.faceState; import cz.fidentis.analyst.core.ControlPanel; import cz.fidentis.analyst.face.HumanFace; import java.awt.Dimension; -import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -20,6 +20,7 @@ import javax.imageio.ImageIO; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.JOptionPane; +import org.imgscalr.Scalr; /** * @@ -299,16 +300,16 @@ public class FaceStatePanel extends ControlPanel { public void showFaceState(String faceName, Path path) { photo.setIcon(getPhoto(path)); - + pathOutput.setText(getPathText(path)); sizeOutput.setText(getSizeText(path)); featurePointsOutput.setText(getFeaturePointsText(path)); previewOutput.setText(getPreviewText(path)); textureOutput.setText(getTextureText(path)); - + verticesOutput.setText(getNumberOfVertices(faceName)); facetsOutput.setText(getNumberOfFacets(faceName)); - loadFeaturePoints(faceName); + loadFeaturePoints(faceName); } @@ -324,7 +325,6 @@ public class FaceStatePanel extends ControlPanel { */ private ImageIcon getPhoto(Path path) { - ImageIcon image; previewFace = null; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); @@ -335,10 +335,14 @@ public class FaceStatePanel extends ControlPanel { try { - previewFace = new ImageIcon(ImageIO.read(preview.toFile()).getScaledInstance((int)screenSize.getWidth() - 200, (int)screenSize.getHeight() - 200, Image.SCALE_FAST)); - image = new ImageIcon(previewFace.getImage().getScaledInstance(240, 160, Image.SCALE_FAST)); + BufferedImage image = ImageIO.read(preview.toFile()); + BufferedImage zoomedImage = Scalr.resize(image, (int)screenSize.getWidth() / 2, (int)screenSize.getHeight() / 2); + BufferedImage smallImage = Scalr.resize(image, 240, 160); + + previewFace = new ImageIcon(zoomedImage); photo.setToolTipText("Click to enlarge the image"); - return image; + return new ImageIcon(smallImage); + } catch (IOException ex) { //Exceptions.printStackTrace(ex);) } diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FeaturePointsFilterPanel.java b/GUI/src/main/java/cz/fidentis/analyst/filter/FeaturePointsFilterPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..41dcfbd0e44d0416b72b7dd9f741bf313c8c1a29 --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FeaturePointsFilterPanel.java @@ -0,0 +1,98 @@ +package cz.fidentis.analyst.filter; + +import cz.fidentis.analyst.feature.FeaturePointType; +import cz.fidentis.analyst.feature.provider.FeaturePointTypeProvider; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.swing.AbstractAction; +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +/** + * + * @author Matej Kovar + */ +public class FeaturePointsFilterPanel extends JPanel { + + private List<JCheckBox> featurePointCheckBoxes; + private List<FeaturePointType> selectedFeaturePoints = new ArrayList<>(); + + /** + * Constructor + */ + public void initComponents() { + + setLayout(new GridBagLayout()); + + // Load all types of feature points + FeaturePointTypeProvider typeProvider = FeaturePointTypeProvider.getInstance(); + Map<Integer, FeaturePointType> fpMap = typeProvider.getFeaturePointTypesById(); + List<FeaturePointType> featurePoints = fpMap.values().stream() + .collect(Collectors.toList()); + + featurePointCheckBoxes = new ArrayList<>(); + + for (int i = 0; i < featurePoints.size(); i++) { + addRow(i, featurePoints.get(i)); + } + + } + + protected void addRow(int row, FeaturePointType featurePoint) { + + GridBagConstraints c1 = new GridBagConstraints(); + c1.insets = new Insets(0, 0, 0, 0); + c1.gridwidth = 1; + c1.gridx = 0; + c1.gridy = row; + c1.anchor = GridBagConstraints.WEST; + c1.fill = GridBagConstraints.NONE; + + JCheckBox checkBox = new JCheckBox(); + checkBox.setSelected(false); + checkBox.setEnabled(false); + checkBox.setText(featurePoint.getName()); + add(checkBox, c1); + featurePointCheckBoxes.add(checkBox); + + checkBox.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + if (!selectedFeaturePoints.remove(featurePoint)) { + selectedFeaturePoints.add(featurePoint); + } + } + }); + } + + /** + * Deselects and disables(enables) all check boxes with each feature point type + * @param enable enables or disables check boxes + */ + public void disableCheckBoxes(boolean enable) { + featurePointCheckBoxes.forEach(ch -> { + + if (!enable) { + ch.setSelected(false); + } + ch.setEnabled(enable); + }); + } + + public List<FeaturePointType> getSelectedFeaturePoints() { + return selectedFeaturePoints; + } + + @Override + public void setEnabled(boolean enable) { + this.getParent().setEnabled(enable); + disableCheckBoxes(enable); + } + +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FilterHistory.java b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..62b5130d6b4751cc8ba7fd3901f0d3e9e05a9ee5 --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterHistory.java @@ -0,0 +1,79 @@ +package cz.fidentis.analyst.filter; + +import java.util.ArrayList; +import java.util.List; + +/** + * History of filtering, holds information of each filtering (which faces were filtered) + * + * @author Matej Kovar + */ +public class FilterHistory { + + // List of each filterings + private List<List<String>> filteredFaces = new ArrayList<>(); + + // Sum of all filtered faces + private int totalFaces = 0; + + /** + * Checks if none faces are filtered + * @return true if none faces are filtered, false otherwise + */ + public boolean isEmpty() { + return filteredFaces.isEmpty(); + } + + /** + * Gets amount of faces filtered + * @return how many faces are currently filtered + */ + public int getTotalFaces() { + return totalFaces; + } + + /** + * Adds newly filtered faces to list + * @param faces list of filtered faces + */ + public void addFaces(List<String> faces) { + if (!faces.isEmpty()) { + filteredFaces.add(faces); + } + totalFaces += faces.size(); + } + + /** + * Removes face which is currently filtered + * @param faceName name of face + */ + public void removeFilteredFace(String faceName) { + filteredFaces.forEach(faces -> { + faces.removeIf(face -> face.equals(faceName)); + }); + totalFaces -= 1; + } + + /** + * Reverts last filtering, i.e. removes lastly filtered faces from list + * @return sum of lastly filtered faces + */ + public int revertLastFiltering() { + int sumFaces = filteredFaces.get(filteredFaces.size() - 1).size(); + filteredFaces.remove(filteredFaces.size() - 1); + totalFaces -= sumFaces; + return sumFaces; + } + + /** + * Removes all faces filtered + * @return amount of filtered faces + */ + public int clear() { + filteredFaces.clear(); + int total = totalFaces; + totalFaces = 0; + return total; + } + +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.form b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.form new file mode 100644 index 0000000000000000000000000000000000000000..eb785f0d86d21b415884229dd24680a7223ab476 --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.form @@ -0,0 +1,303 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="filterPanel" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="filterPanel" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="filterPanel"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Filter settings"> + <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.filterPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Font PropertyName="font" name="Dialog" size="14" style="1"/> + </TitledBorder> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="47" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="hasSelectedFPCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="hasFPCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="hasNotFPCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="51" max="-2" attributes="0"/> + <Component id="featurePointsPanel" min="-2" pref="261" max="-2" attributes="0"/> + <EmptySpace pref="31" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="hasTextCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="hasNotTextCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="40" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="hasNotTextTextfield" pref="124" max="32767" attributes="0"/> + <Component id="hasTextTextfield" pref="124" max="32767" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="clearFilteringButton" min="-2" max="-2" attributes="0"/> + <EmptySpace min="-2" pref="68" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="103" groupAlignment="0" max="-2" attributes="0"> + <Component id="revertLastFilteringButton" max="32767" attributes="0"/> + <Component id="applyFilterButton" max="32767" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="62" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="byNameLabel" min="-2" max="-2" attributes="0"/> + <Component id="byFPLabel" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="28" max="-2" attributes="0"/> + <Component id="byFPLabel" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="hasFPCheckbox" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="hasSelectedFPCheckbox" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Component id="hasNotFPCheckbox" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="featurePointsPanel" min="-2" pref="133" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="32" max="-2" attributes="0"/> + <Component id="byNameLabel" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="hasTextCheckbox" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="hasTextTextfield" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="hasNotTextCheckbox" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="hasNotTextTextfield" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace pref="178" max="32767" attributes="0"/> + <Component id="revertLastFilteringButton" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="applyFilterButton" alignment="3" min="-2" pref="37" max="-2" attributes="0"/> + <Component id="clearFilteringButton" alignment="3" min="-2" pref="37" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="48" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="byFPLabel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="13" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.byFPLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="hasFPCheckbox"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasFPCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="hasSelectedFPCheckbox"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasSelectedFPCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="hasNotFPCheckbox"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasNotFPCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Container class="javax.swing.JScrollPane" name="featurePointsPanel"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Feature points"> + <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.featurePointsPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + <Font PropertyName="font" name="Dialog" size="11" style="1"/> + </TitledBorder> + </Border> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="cz.fidentis.analyst.filter.FeaturePointsFilterPanel" name="featurePointsFilterPanel1"> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="249" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="110" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + </Layout> + </Container> + </SubComponents> + </Container> + <Component class="javax.swing.JLabel" name="byNameLabel"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="13" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.byNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="hasTextCheckbox"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasTextCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="hasTextTextfield"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasTextTextfield.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="hasNotTextCheckbox"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="12" style="0"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasNotTextCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="hasNotTextTextfield"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.hasNotTextTextfield.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="applyFilterButton"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="14" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.applyFilterButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="applyFilterButtonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="clearFilteringButton"> + <Properties> + <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> + <Font name="Tahoma" size="14" style="1"/> + </Property> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.clearFilteringButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="clearFilteringButtonActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="revertLastFilteringButton"> + <Properties> + <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> + <ResourceString bundle="cz/fidentis/analyst/filter/Bundle.properties" key="FilterPanel.revertLastFilteringButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> + </Property> + <Property name="enabled" type="boolean" value="false"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="revertLastFilteringButtonActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.java b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..73ed5e45bb51a879de245901adfd1e8fd7acc45f --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterPanel.java @@ -0,0 +1,503 @@ +package cz.fidentis.analyst.filter; + +import cz.fidentis.analyst.core.ControlPanel; +import cz.fidentis.analyst.core.ProgressDialog; +import cz.fidentis.analyst.face.HumanFace; +import cz.fidentis.analyst.feature.FeaturePointType; +import cz.fidentis.analyst.project.ProjectPanel; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.swing.ImageIcon; +import javax.swing.JOptionPane; +import javax.swing.JTable; +import javax.swing.SwingWorker; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * + * @author Matej Kovar + */ +public class FilterPanel extends ControlPanel { + + private ProjectPanel projectPanel; + + private List<FeaturePointType> selectedFeaturePoints = new ArrayList<>(); + + private FilterHistory filterHistory = new FilterHistory(); + + private List<FilterSection> sections = new ArrayList<>(); + + private ActionListener listenerChangeIcon; + + public static final String ICON_FILTER_OFF = "filter_off28x28.png"; + public static final String ICON_FILTER_ON = "filter_on28x28.png"; + public static final String NAME = "Filter"; + + /** + * Constructor + * @param projectPanel ProjectPanel + */ + public FilterPanel(ProjectPanel projectPanel) { + this.setName(NAME); + this.projectPanel = projectPanel; + initComponents(); + + featurePointsFilterPanel1.initComponents(); + initSections(); + + setTableCellRenderer(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + filterPanel = new javax.swing.JPanel(); + byFPLabel = new javax.swing.JLabel(); + hasFPCheckbox = new javax.swing.JCheckBox(); + hasSelectedFPCheckbox = new javax.swing.JCheckBox(); + hasNotFPCheckbox = new javax.swing.JCheckBox(); + featurePointsPanel = new javax.swing.JScrollPane(); + featurePointsFilterPanel1 = new cz.fidentis.analyst.filter.FeaturePointsFilterPanel(); + byNameLabel = new javax.swing.JLabel(); + hasTextCheckbox = new javax.swing.JCheckBox(); + hasTextTextfield = new javax.swing.JTextField(); + hasNotTextCheckbox = new javax.swing.JCheckBox(); + hasNotTextTextfield = new javax.swing.JTextField(); + applyFilterButton = new javax.swing.JButton(); + clearFilteringButton = new javax.swing.JButton(); + revertLastFilteringButton = new javax.swing.JButton(); + + filterPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.filterPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 14))); // NOI18N + + byFPLabel.setFont(new java.awt.Font("Tahoma", 1, 13)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(byFPLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.byFPLabel.text")); // NOI18N + + hasFPCheckbox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hasFPCheckbox, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasFPCheckbox.text")); // NOI18N + + hasSelectedFPCheckbox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hasSelectedFPCheckbox, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasSelectedFPCheckbox.text")); // NOI18N + + hasNotFPCheckbox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hasNotFPCheckbox, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasNotFPCheckbox.text")); // NOI18N + + featurePointsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.featurePointsPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 11))); // NOI18N + featurePointsPanel.setEnabled(false); + + javax.swing.GroupLayout featurePointsFilterPanel1Layout = new javax.swing.GroupLayout(featurePointsFilterPanel1); + featurePointsFilterPanel1.setLayout(featurePointsFilterPanel1Layout); + featurePointsFilterPanel1Layout.setHorizontalGroup( + featurePointsFilterPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 249, Short.MAX_VALUE) + ); + featurePointsFilterPanel1Layout.setVerticalGroup( + featurePointsFilterPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 110, Short.MAX_VALUE) + ); + + featurePointsPanel.setViewportView(featurePointsFilterPanel1); + + byNameLabel.setFont(new java.awt.Font("Tahoma", 1, 13)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(byNameLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.byNameLabel.text")); // NOI18N + + hasTextCheckbox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hasTextCheckbox, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasTextCheckbox.text")); // NOI18N + + hasTextTextfield.setText(org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasTextTextfield.text")); // NOI18N + hasTextTextfield.setEnabled(false); + + hasNotTextCheckbox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hasNotTextCheckbox, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasNotTextCheckbox.text")); // NOI18N + + hasNotTextTextfield.setText(org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasNotTextTextfield.text")); // NOI18N + hasNotTextTextfield.setEnabled(false); + + applyFilterButton.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(applyFilterButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.applyFilterButton.text")); // NOI18N + applyFilterButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + applyFilterButtonActionPerformed(evt); + } + }); + + clearFilteringButton.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(clearFilteringButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.clearFilteringButton.text")); // NOI18N + clearFilteringButton.setEnabled(false); + clearFilteringButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + clearFilteringButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(revertLastFilteringButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.revertLastFilteringButton.text")); // NOI18N + revertLastFilteringButton.setEnabled(false); + revertLastFilteringButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + revertLastFilteringButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout filterPanelLayout = new javax.swing.GroupLayout(filterPanel); + filterPanel.setLayout(filterPanelLayout); + filterPanelLayout.setHorizontalGroup( + filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(filterPanelLayout.createSequentialGroup() + .addGap(47, 47, 47) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(filterPanelLayout.createSequentialGroup() + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hasSelectedFPCheckbox) + .addComponent(hasFPCheckbox) + .addComponent(hasNotFPCheckbox)) + .addGap(51, 51, 51) + .addComponent(featurePointsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(31, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filterPanelLayout.createSequentialGroup() + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(filterPanelLayout.createSequentialGroup() + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hasTextCheckbox) + .addComponent(hasNotTextCheckbox)) + .addGap(40, 40, 40) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(hasNotTextTextfield, javax.swing.GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE) + .addComponent(hasTextTextfield, javax.swing.GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filterPanelLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(clearFilteringButton) + .addGap(68, 68, 68))) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(revertLastFilteringButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(applyFilterButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(62, 62, 62)))) + .addGroup(filterPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(byNameLabel) + .addComponent(byFPLabel)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + filterPanelLayout.setVerticalGroup( + filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(filterPanelLayout.createSequentialGroup() + .addGap(28, 28, 28) + .addComponent(byFPLabel) + .addGap(18, 18, 18) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(filterPanelLayout.createSequentialGroup() + .addComponent(hasFPCheckbox) + .addGap(18, 18, 18) + .addComponent(hasSelectedFPCheckbox) + .addGap(18, 18, 18) + .addComponent(hasNotFPCheckbox)) + .addComponent(featurePointsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(32, 32, 32) + .addComponent(byNameLabel) + .addGap(18, 18, 18) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(hasTextCheckbox) + .addComponent(hasTextTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(hasNotTextCheckbox) + .addComponent(hasNotTextTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 178, Short.MAX_VALUE) + .addComponent(revertLastFilteringButton) + .addGap(18, 18, 18) + .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(applyFilterButton, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(clearFilteringButton, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(48, 48, 48)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + }// </editor-fold>//GEN-END:initComponents + + private void initSections() { + + FilterSection featurePointsSection = new FilterSection(); + featurePointsSection.add(hasFPCheckbox, null); + featurePointsSection.add(hasSelectedFPCheckbox, featurePointsFilterPanel1); + featurePointsSection.add(hasNotFPCheckbox, null); + sections.add(featurePointsSection); + + FilterSection nameSection = new FilterSection(); + nameSection.add(hasTextCheckbox, hasTextTextfield); + nameSection.add(hasNotTextCheckbox, hasNotTextTextfield); + sections.add(nameSection); + } + + public FilterHistory getFilterHistory() { + return filterHistory; + } + + private void clearFilteringButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearFilteringButtonActionPerformed + clearFiltering(); + }//GEN-LAST:event_clearFilteringButtonActionPerformed + + private void applyFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyFilterButtonActionPerformed + applyFilter(); + clearFilteringButton.setEnabled(!filterHistory.isEmpty()); + listenerChangeIcon.actionPerformed(evt); + revertLastFilteringButton.setEnabled(!filterHistory.isEmpty()); + }//GEN-LAST:event_applyFilterButtonActionPerformed + + private void revertLastFilteringButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_revertLastFilteringButtonActionPerformed + + projectPanel.deselectAllRows(); + + // sum of rows which were lastly filtered + int totalRows = filterHistory.revertLastFiltering(); + + // move rows from the bottom of the table to the beginning of the table + projectPanel.getModel().unfilterRows(totalRows); + + listenerChangeIcon.actionPerformed(evt); + revertLastFilteringButton.setEnabled(!filterHistory.isEmpty()); + clearFilteringButton.setEnabled(!filterHistory.isEmpty()); + projectPanel.repaint(); + }//GEN-LAST:event_revertLastFilteringButtonActionPerformed + + @Override + public ImageIcon getIcon() { + if (filterHistory.isEmpty()) { + return new ImageIcon(FilterPanel.class.getClassLoader().getResource("/" + ICON_FILTER_OFF)); + } + return new ImageIcon(FilterPanel.class.getClassLoader().getResource("/" + ICON_FILTER_ON)); + + } + + public void setListenerChangeIcon(ActionListener listenerChangeIcon) { + this.listenerChangeIcon = listenerChangeIcon; + } + + /** + * Sets ActionListener to apply filter button + * @param applyFilterListener ActionListener + */ + public void setFilterActionListener(ActionListener applyFilterListener) { + applyFilterButton.addActionListener(applyFilterListener); + + } + + /** + * Sets ActionListener to cancel filter mode button + * @param listenerCancelFilter ActionListener + */ + public void setCancelFilterActionListener(ActionListener listenerCancelFilter) { + clearFilteringButton.addActionListener(listenerCancelFilter); + } + + public List<FeaturePointType> getSelectedFeaturePointsFilter() { + return selectedFeaturePoints; + } + + /** + * Checks whether face should be filtered based on feature points filter options + * @param faceName String name of face + * @return true if face should be filtered, false otherwise + */ + public boolean applyByFeaturePointsFilter(String faceName) { + + boolean hasFP = projectPanel.getProject().hasFPByName(faceName); + + // Has some feature point + if (hasFPCheckbox.isSelected() && !hasFP) { + return true; + } + + // Has not feature points + if (hasNotFPCheckbox.isSelected() && hasFP) { + return true; + } + + // Has selected feature points (from feature points panel) + if (hasSelectedFPCheckbox.isSelected() && + !featurePointsFilterPanel1.getSelectedFeaturePoints().isEmpty()) { + HumanFace face = projectPanel.getProject().loadFace(faceName); + + if (face != null && Collections.disjoint(face.getFeaturePoints().stream() + .map(fp -> fp.getFeaturePointType()) + .collect(Collectors.toList()), featurePointsFilterPanel1.getSelectedFeaturePoints())) { + return true; + } + } + + return false; + } + + /** + * Checks whether face should be filtered based on name filter options + * @param faceName String name of face + * @return true if face should be filtered, false otherwise + */ + public boolean applyByNameFilter(String faceName) { + + // Has text + if (hasTextCheckbox.isSelected() && !faceName.contains(hasTextTextfield.getText())) { + return true; + } + + // Has not text + return hasNotTextCheckbox.isSelected() && faceName.contains(hasNotTextTextfield.getText()); + } + + /** + * Applies given filters to face and checks whether face should be filtered or not + * @param faceName String name of face + * @return true if face should be filtered, false otherwise + */ + public boolean applyFilterOptions(String faceName) { + + return applyByFeaturePointsFilter(faceName) || applyByNameFilter(faceName); + + } + + /** + * Starts filtering faces based on filter configuration + */ + public void applyFilter() { + + projectPanel.deselectAllRows(); + + ProgressDialog progressDialog = new ProgressDialog(filterPanel, "Filtering faces"); + FilterTask task = new FilterTask(projectPanel.getModel(), this, progressDialog); + + task.addPropertyChangeListener((PropertyChangeEvent evt) -> { + if ("state".equals(evt.getPropertyName()) && (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) { + + // Task finished successfully, remove selected faces + if (task.getCompleted()) { + + int total = task.getFilteredRows().size(); + filterFaces(task.getFilteredRows()); + + JOptionPane.showMessageDialog(filterPanel, + String.format("Filtering done, %d face(s) filtered", total), + "Filter", + JOptionPane.INFORMATION_MESSAGE); + + } + } + }); + progressDialog.runTask(task); + } + + /** + * Adds filtered (selected) models to the end of the list + */ + public void filterFaces(List<Integer> filteredRows) { + + List<String> selectedFaces = new ArrayList<>(); + Collections.sort(filteredRows, Collections.reverseOrder()); + + // Moves selected (filtered) faces to the end of the list + filteredRows.forEach(row -> { + String faceName = projectPanel.getModel().getValueAt(row, 1).toString(); + selectedFaces.add(faceName); + projectPanel.getModel().filterRow(row); + }); + + filterHistory.addFaces(selectedFaces); + projectPanel.checkFaceState(null, false); + projectPanel.repaint(); + } + + /** + * Cancels filtering + */ + public void clearFiltering() { + int totalFaces = filterHistory.clear(); + projectPanel.getModel().unfilterRows(totalFaces); + + projectPanel.deselectAllRows(); + projectPanel.repaint(); + + sections.forEach(section -> { + section.disableAllComponents(); + }); + revertLastFilteringButton.setEnabled(false); + clearFilteringButton.setEnabled(false); + listenerChangeIcon.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null)); + } + + /** + * Sets table cell renderer needed for coloring filtered rows + * If row is filtered, Color.lightGray font color is set + */ + private void setTableCellRenderer() { + + projectPanel.getTable().setDefaultRenderer(String.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + + Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + if (projectPanel.getModel().getRowCount() > 0) { + + String faceName = projectPanel.getModel().getValueAt(row, 1).toString(); + + // checks if face in this row is filtered or not and colors text if yes + if (row >= projectPanel.getModel().getRowCount() - filterHistory.getTotalFaces()) { + c.setForeground(Color.lightGray); + projectPanel.getModel().disableRow(row, projectPanel.getProject().getCfg().getPathToFaceByName(faceName)); + + } else { + c.setForeground(Color.black); + projectPanel.getModel().enableRow(row, projectPanel.getProject().getCfg().getPathToFaceByName(faceName)); + } + + } + return c; + }}); + } + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton applyFilterButton; + private javax.swing.JLabel byFPLabel; + private javax.swing.JLabel byNameLabel; + private javax.swing.JButton clearFilteringButton; + private cz.fidentis.analyst.filter.FeaturePointsFilterPanel featurePointsFilterPanel1; + private javax.swing.JScrollPane featurePointsPanel; + private javax.swing.JPanel filterPanel; + private javax.swing.JCheckBox hasFPCheckbox; + private javax.swing.JCheckBox hasNotFPCheckbox; + private javax.swing.JCheckBox hasNotTextCheckbox; + private javax.swing.JTextField hasNotTextTextfield; + private javax.swing.JCheckBox hasSelectedFPCheckbox; + private javax.swing.JCheckBox hasTextCheckbox; + private javax.swing.JTextField hasTextTextfield; + private javax.swing.JButton revertLastFilteringButton; + // End of variables declaration//GEN-END:variables + +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FilterSection.java b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterSection.java new file mode 100644 index 0000000000000000000000000000000000000000..7b7b7a3cbbde075e9b44c883d60d126f76172f03 --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterSection.java @@ -0,0 +1,102 @@ +package cz.fidentis.analyst.filter; + +import java.awt.event.ActionEvent; +import java.util.HashMap; +import java.util.Map; +import javax.swing.AbstractAction; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JTextField; + +/** + * + * @author Matej Kovar + */ +public class FilterSection { + + // key is checkbox, value is list of all additional + // components checkbox has + private Map<JCheckBox, JComponent> options = new HashMap<>(); + + /** + * Adds new pair of checkbox and corresponding additional JComponent to this checkbox + * @param checkbox JCheckBox + * @param additional JComponent, null if checkbox doesn't need another component + */ + public void add(JCheckBox checkbox, JComponent additional) { + + options.put(checkbox, additional); + checkbox.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + checkboxSelected(checkbox, checkbox.isSelected()); + } + + }); + } + + /** + * Enables/disables JComponent which is associated with checkbox + * @param checkbox JCheckbox + * @param enable Boolean - true if checkbox is selected, false otherwise + */ + private void checkboxSelected(JCheckBox checkbox, boolean enable) { + + JComponent c = options.get(checkbox); + if (c != null) { + c.setEnabled(enable); + } + + if (c instanceof JTextField) { + ((JTextField) c).setText(""); + } + + disableOtherComponents(checkbox); + } + + /** + * Disable other components from this section, i.e. disables other checkboxes + * and their associated JComponents + * @param checkbox JCheckbox + */ + private void disableOtherComponents(JCheckBox checkbox) { + + options.keySet() + .stream() + .filter(key -> (key != checkbox)) + .map(key -> { + key.setSelected(false); + return key; + }) + .forEachOrdered(key -> { + JComponent c = options.get(key); + if (c != null) { + c.setEnabled(false); + } + if (c instanceof JTextField) { + ((JTextField) c).setText(""); + } + }); + } + + /** + * Disables all checkboxes and components in this section + */ + public void disableAllComponents() { + options.keySet() + .stream() + .map(key -> { + key.setSelected(false); + return key; + }) + .forEachOrdered(key -> { + JComponent c = options.get(key); + if (c != null) { + c.setEnabled(false); + } + if (c instanceof JTextField) { + ((JTextField) c).setText(""); + } + }); + } +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/filter/FilterTask.java b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterTask.java new file mode 100644 index 0000000000000000000000000000000000000000..54f4bfd48b053c802fa21b0436a8e317353df518 --- /dev/null +++ b/GUI/src/main/java/cz/fidentis/analyst/filter/FilterTask.java @@ -0,0 +1,86 @@ +package cz.fidentis.analyst.filter; + +import cz.fidentis.analyst.core.ProgressDialog; +import cz.fidentis.analyst.project.ModelsTableModel; +import java.util.ArrayList; +import java.util.List; +import javax.swing.SwingWorker; + +/** + * A task that filters table and selects models which should be removed + * + * @author Matej Kovar + */ +public class FilterTask extends SwingWorker<Boolean, Integer>{ + + private final FilterPanel filterPanel; + private ModelsTableModel model; + private final ProgressDialog progressDialog; + + private boolean completed = false; + + private List<Integer> filteredRows = new ArrayList<>(); + + /** + * Constructor + * + * @param model ModelsTableModel + * @param filterPanel FilterPanel + * @param progressDialog ProgressDialog + */ + public FilterTask(ModelsTableModel model, FilterPanel filterPanel, ProgressDialog progressDialog) { + + this.filterPanel = filterPanel; + this.model = model; + this.progressDialog = progressDialog; + } + + @Override + protected Boolean doInBackground() throws Exception { + + filteredRows.clear(); + + // Selects only models from list which are not filtered yet (are not in the bottom of list) + for (int row = 0; row < model.getRowCount() - filterPanel.getFilterHistory().getTotalFaces(); row++) { + + if (isCancelled()) { + completed = false; + filteredRows.clear(); + return false; + } + + String faceName = model.getValueAt(row, 1).toString(); + if (filterPanel.applyFilterOptions(faceName)) { + + filteredRows.add(row); + } + + int progress = (int)Math.round(100.0 * (row + 1) / model.getRowCount()); + progressDialog.setValue(progress); + } + + completed = true; + return true; + } + + @Override + protected void done() { + progressDialog.dispose(); + + if (isCancelled()) { + completed = false; + filteredRows.clear(); + return; + } + completed = true; + } + + public boolean getCompleted() { + return completed; + } + + public List<Integer> getFilteredRows() { + return filteredRows; + } + +} diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form deleted file mode 100644 index c8e1b487a3fe9dc0aae95a17f2430572efd0a0a1..0000000000000000000000000000000000000000 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form +++ /dev/null @@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> - -<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> - <AuxValues> - <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> - <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> - <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> - <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> - <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> - <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> - <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> - </AuxValues> - - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace max="-2" attributes="0"/> - <Component id="filterPanel" max="32767" attributes="0"/> - <EmptySpace max="-2" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace max="-2" attributes="0"/> - <Component id="filterPanel" min="-2" max="-2" attributes="0"/> - <EmptySpace pref="270" max="32767" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - </Layout> - <SubComponents> - <Container class="javax.swing.JPanel" name="filterPanel"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> - <TitledBorder title="Filter settings"> - <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.filterPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - <Font PropertyName="font" name="Dialog" size="12" style="1"/> - </TitledBorder> - </Border> - </Property> - </Properties> - - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="38" max="-2" attributes="0"/> - <Group type="103" groupAlignment="1" attributes="0"> - <Component id="applyFilterButton" min="-2" max="-2" attributes="0"/> - <Group type="103" groupAlignment="0" attributes="0"> - <Component id="alphabetical" min="-2" max="-2" attributes="0"/> - <Component id="hasKD" min="-2" max="-2" attributes="0"/> - <Component id="hasFP" min="-2" max="-2" attributes="0"/> - </Group> - </Group> - <EmptySpace pref="201" max="32767" attributes="0"/> - <Component id="loadAllModelsButton" min="-2" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="89" max="-2" attributes="0"/> - </Group> - <Group type="102" alignment="1" attributes="0"> - <EmptySpace max="32767" attributes="0"/> - <Component id="warningLabel" min="-2" max="-2" attributes="0"/> - <EmptySpace type="unrelated" max="-2" attributes="0"/> - <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="40" max="-2" attributes="0"/> - <Component id="hasFP" min="-2" max="-2" attributes="0"/> - <EmptySpace type="separate" max="-2" attributes="0"/> - <Component id="hasKD" min="-2" max="-2" attributes="0"/> - <EmptySpace type="separate" max="-2" attributes="0"/> - <Component id="alphabetical" min="-2" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="19" max="-2" attributes="0"/> - <Group type="103" groupAlignment="1" attributes="0"> - <Component id="warningLabel" min="-2" max="-2" attributes="0"/> - <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/> - </Group> - <EmptySpace min="-2" pref="23" max="-2" attributes="0"/> - <Group type="103" groupAlignment="3" attributes="0"> - <Component id="applyFilterButton" alignment="3" min="-2" max="-2" attributes="0"/> - <Component id="loadAllModelsButton" alignment="3" min="-2" max="-2" attributes="0"/> - </Group> - <EmptySpace pref="69" max="32767" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - </Layout> - <SubComponents> - <Component class="javax.swing.JCheckBox" name="hasFP"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.hasFP.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hasFPActionPerformed"/> - </Events> - </Component> - <Component class="javax.swing.JCheckBox" name="hasKD"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.hasKD.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hasKDActionPerformed"/> - </Events> - </Component> - <Component class="javax.swing.JCheckBox" name="alphabetical"> - <Properties> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.alphabetical.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="alphabeticalActionPerformed"/> - </Events> - </Component> - <Component class="javax.swing.JButton" name="applyFilterButton"> - <Properties> - <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> - <Font name="Tahoma" size="12" style="1"/> - </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.applyFilterButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - <Property name="enabled" type="boolean" value="false"/> - </Properties> - </Component> - <Component class="javax.swing.JLabel" name="warningLabel"> - <Properties> - <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> - <Image iconType="3" name="/warning16x16.png"/> - </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="warningLabel.setVisible(false);"/> - </AuxValues> - </Component> - <Component class="javax.swing.JLabel" name="faceNotLoadedLabel"> - <Properties> - <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> - <Font name="Tahoma" size="12" style="1"/> - </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.faceNotLoadedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="faceNotLoadedLabel.setVisible(false);"/> - </AuxValues> - </Component> - <Component class="javax.swing.JButton" name="loadAllModelsButton"> - <Properties> - <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> - <Font name="Tahoma" size="12" style="1"/> - </Property> - <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> - <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.loadAllModelsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <AuxValues> - <AuxValue name="JavaCodeGenerator_ListenersCodePost" type="java.lang.String" value="loadAllModelsButton.setVisible(false);"/> - </AuxValues> - </Component> - </SubComponents> - </Container> - </SubComponents> -</Form> diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java deleted file mode 100644 index 4a56dafd0156ca3363690dfdd0148eed4ef69108..0000000000000000000000000000000000000000 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java +++ /dev/null @@ -1,221 +0,0 @@ -package cz.fidentis.analyst.project; - -import cz.fidentis.analyst.core.ControlPanel; -import java.awt.event.ActionListener; -import javax.swing.ImageIcon; -import javax.swing.JCheckBox; - -/** - * - * @author Matej Kovar - */ -public class FilterPanel extends ControlPanel { - - private boolean kdTreeFilter = false; - private boolean featurePointsFilter = false; - private boolean alphabeticalFilter = false; - - - public static final String ICON = "filter28x28.png"; - public static final String NAME = "Filter"; - - /** - * Creates new form FilterPanel - */ - public FilterPanel(ActionListener listenerLoadAllFaces) { - this.setName(NAME); - initComponents(); - loadAllModelsButton.addActionListener(listenerLoadAllFaces); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents - private void initComponents() { - - filterPanel = new javax.swing.JPanel(); - hasFP = new javax.swing.JCheckBox(); - hasKD = new javax.swing.JCheckBox(); - alphabetical = new javax.swing.JCheckBox(); - applyFilterButton = new javax.swing.JButton(); - warningLabel = new javax.swing.JLabel(); - faceNotLoadedLabel = new javax.swing.JLabel(); - loadAllModelsButton = new javax.swing.JButton(); - - filterPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.filterPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N - - org.openide.awt.Mnemonics.setLocalizedText(hasFP, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasFP.text")); // NOI18N - hasFP.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - hasFPActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(hasKD, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasKD.text")); // NOI18N - hasKD.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - hasKDActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(alphabetical, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.alphabetical.text")); // NOI18N - alphabetical.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - alphabeticalActionPerformed(evt); - } - }); - - applyFilterButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(applyFilterButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.applyFilterButton.text")); // NOI18N - applyFilterButton.setEnabled(false); - - warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/warning16x16.png"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.warningLabel.text")); // NOI18N - warningLabel.setVisible(false); - - faceNotLoadedLabel.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(faceNotLoadedLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.faceNotLoadedLabel.text")); // NOI18N - faceNotLoadedLabel.setVisible(false); - - loadAllModelsButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(loadAllModelsButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.loadAllModelsButton.text")); // NOI18N - loadAllModelsButton.setVisible(false); - - javax.swing.GroupLayout filterPanelLayout = new javax.swing.GroupLayout(filterPanel); - filterPanel.setLayout(filterPanelLayout); - filterPanelLayout.setHorizontalGroup( - filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(filterPanelLayout.createSequentialGroup() - .addGap(38, 38, 38) - .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(applyFilterButton) - .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(alphabetical) - .addComponent(hasKD) - .addComponent(hasFP))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 201, Short.MAX_VALUE) - .addComponent(loadAllModelsButton) - .addGap(89, 89, 89)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filterPanelLayout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(warningLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(faceNotLoadedLabel) - .addGap(22, 22, 22)) - ); - filterPanelLayout.setVerticalGroup( - filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(filterPanelLayout.createSequentialGroup() - .addGap(40, 40, 40) - .addComponent(hasFP) - .addGap(18, 18, 18) - .addComponent(hasKD) - .addGap(18, 18, 18) - .addComponent(alphabetical) - .addGap(19, 19, 19) - .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(warningLabel) - .addComponent(faceNotLoadedLabel)) - .addGap(23, 23, 23) - .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(applyFilterButton) - .addComponent(loadAllModelsButton)) - .addContainerGap(69, Short.MAX_VALUE)) - ); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(filterPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(270, Short.MAX_VALUE)) - ); - }// </editor-fold>//GEN-END:initComponents - - /** - * Sets attribute to corresponding value based on checkbox - * @param evt - */ - private void hasFPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hasFPActionPerformed - featurePointsFilter = (((JCheckBox)evt.getSource()).isSelected()); - }//GEN-LAST:event_hasFPActionPerformed - - /** - * Sets attribute to corresponding value based on checkbox - * @param evt - */ - private void hasKDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hasKDActionPerformed - kdTreeFilter = (((JCheckBox)evt.getSource()).isSelected()); - }//GEN-LAST:event_hasKDActionPerformed - - /** - * Sets attribute to corresponding value based on checkbox - * @param evt - */ - private void alphabeticalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_alphabeticalActionPerformed - alphabeticalFilter = (((JCheckBox)evt.getSource()).isSelected()); - }//GEN-LAST:event_alphabeticalActionPerformed - - @Override - public ImageIcon getIcon() { - return new ImageIcon(FilterPanel.class.getClassLoader().getResource("/" + ICON)); - } - - /** - * Sets ActionListener to apply filter button - * @param applyFilterListener ActionListener - */ - public void setFilterActionListener(ActionListener applyFilterListener) { - applyFilterButton.addActionListener(applyFilterListener); - } - - public boolean isKdTreeFilter() { - return kdTreeFilter; - } - - public boolean isFeaturePointsFilter() { - return featurePointsFilter; - } - - public boolean isAlphabeticalFilter() { - return alphabeticalFilter; - } - - /** - * Checks if all faces in list are loaded. If not, button which loads all - * faces from list shows up - * @param isAllFacesLoaded Boolean - */ - public void checkAllFacesLoaded(boolean isAllFacesLoaded) { - - warningLabel.setVisible(!isAllFacesLoaded); - faceNotLoadedLabel.setVisible(!isAllFacesLoaded); - loadAllModelsButton.setVisible(!isAllFacesLoaded); - applyFilterButton.setEnabled(isAllFacesLoaded); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JCheckBox alphabetical; - private javax.swing.JButton applyFilterButton; - private javax.swing.JLabel faceNotLoadedLabel; - private javax.swing.JPanel filterPanel; - private javax.swing.JCheckBox hasFP; - private javax.swing.JCheckBox hasKD; - private javax.swing.JButton loadAllModelsButton; - private javax.swing.JLabel warningLabel; - // End of variables declaration//GEN-END:variables - -} diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java b/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java index 980ca3270b0a90925c9c2df2aac3448d4b1f0f2f..ec2fe1572c3498db570e3b6da26c609abf7f7d21 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java @@ -1,8 +1,15 @@ package cz.fidentis.analyst.project; +import cz.fidentis.analyst.faceState.FaceStatePanel; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; +import java.awt.Image; +import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.table.DefaultTableModel; @@ -16,19 +23,22 @@ import org.imgscalr.Scalr; */ public class ModelsTableModel extends DefaultTableModel { - //private final ImageIcon notCheck = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "notCheck16x16.png")); - //private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png")); + // Black silhouette inserted when face has no preview private final ImageIcon previewBasic = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face32x32.png")); + private final ImageIcon previewBasicGray = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face_gray32x32.png")); + + // List of previews of faces which are currently filtered + private List<Path> pathsToFilteredFaces = new ArrayList<>(); + private Integer filteredRows = 0; + + /** * Constructor - * @param columnNames names of Columns - * @param rowCount number of rows */ - public ModelsTableModel(Object[] columnNames, int rowCount) { - super(columnNames, rowCount); + public ModelsTableModel() { + super(new Object[]{"", "Models", "Preview"}, 0); } - private Class[] types = new Class [] { java.lang.Boolean.class, java.lang.String.class, ImageIcon.class }; @@ -43,8 +53,66 @@ public class ModelsTableModel extends DefaultTableModel { @Override public boolean isCellEditable(int rowIndex, int columnIndex) { + + if (rowIndex >= getRowCount() - filteredRows) { + return false; + } return canEdit [columnIndex]; } + + @Override + public void setRowCount(int rowCount) { + super.setRowCount(rowCount); + if (rowCount == 0) { + pathsToFilteredFaces.clear(); + filteredRows = 0; + } + } + + @Override + public void removeRow(int row) { + super.removeRow(row); + + String faceName = this.getValueAt(row, 1).toString(); + + pathsToFilteredFaces.removeIf(path -> { + return path.toString().substring(path.toString() + .lastIndexOf(File.separatorChar) + 1, + path.toString().lastIndexOf('.')).equals(faceName); + }); + } + + /** + * (De)selects all editable rows based on value passed to this function + * @param selection (de)selects all editable rows + */ + public void setAllRowsSelection(boolean selection) { + + for (int row = 0; row < this.getRowCount() - filteredRows; row++) { + + this.setValueAt(selection, row, 0); + + } + } + + /** + * Inflates selection + */ + public void inflateSelection() { + + for (int row = 0; row < this.getRowCount() - filteredRows; row++) { + + + + if (this.getValueAt(row, 0) == (Object) true) { + this.setValueAt(false, row, 0); + } else { + this.setValueAt(true, row, 0); + } + + } + } + public Class[] getTypes() { return types;} @@ -58,38 +126,148 @@ public class ModelsTableModel extends DefaultTableModel { this.canEdit = canEdit; } + /** + * Converts a given Image into a BufferedImage + * + * @param img The Image to be converted + * @return The converted BufferedImage + */ + public static BufferedImage toBufferedImage(Image img) { + + if (img instanceof BufferedImage) { + return (BufferedImage) img; + } + + if (img == null) { + return null; + } + + // Create a buffered image with transparency + BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); + + // Draw the image on to the buffered image + Graphics2D bGr = bimage.createGraphics(); + bGr.drawImage(img, 0, 0, null); + bGr.dispose(); + + // Return the buffered image + return bimage; + } + + /** + * Disables row because it is being filtered, i.e. disables preview + * @param row which is currently filtered + */ + public void disableRow(int row, Path path) { + if (path != null && !pathsToFilteredFaces.contains(path)) { + + Image iconImage = ((ImageIcon)this.getValueAt(row, 2)).getImage(); + Path previewPath = this.getPreviewPath(path); + + if (previewPath == null || !previewPath.toFile().exists()) { + + this.setValueAt(previewBasicGray, row, 2); + + } else { + + BufferedImage image = toBufferedImage(iconImage); + + // Scalr.OP_DARKER passed 5 times to grey preview by 50% + image = Scalr.apply(image, Scalr.OP_DARKER, Scalr.OP_DARKER, + Scalr.OP_DARKER, Scalr.OP_DARKER, Scalr.OP_DARKER); + this.setValueAt(new ImageIcon(image), row, 2); + } + + pathsToFilteredFaces.add(path); + } + } + + /** + * Enables row because it is not longer filtered, i.e. enables preview + * @param row which is not longer filtered + */ + public void enableRow(int row, Path path) { + if (path != null && pathsToFilteredFaces.contains(path)) { + + Path previewPath = this.getPreviewPath(path); + ImageIcon preview = null; + + if (previewPath == null || !previewPath.toFile().exists()) { + preview = previewBasic; + } else { + try { + BufferedImage image = ImageIO.read(previewPath.toFile()); + + // Scale image to fit into column + BufferedImage scaledImage = Scalr.resize(image, 70, 55); + preview = new ImageIcon(scaledImage); + + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + + } + + this.setValueAt(preview, row, 2); + pathsToFilteredFaces.remove(path); + } + } + + /** + * Moves row to the bottom of the list (to filtered rows) + * @param row index of row which is about to be moved/filtered + */ + public void filterRow(int row) { + moveRow(row, row, getRowCount() - 1); + filteredRows++; + } + + /** + * Moves filtered rows to the top of the list (unfilters rows) + * @param totalRows amount of rows which are about to be moved to the top + */ + public void unfilterRows(int totalRows) { + if (totalRows != 0) { + moveRow(getRowCount() - totalRows, getRowCount() - 1, 0); + filteredRows -= totalRows; + } + + } + + /** + * Gets path to preview image + * @param path path to face + * @return path to preview if preview is found, null otherwise + */ + public Path getPreviewPath(Path path) { + + Path preview = Paths.get(path.toString().substring(0, path.toString().lastIndexOf(".")).concat("_preview.jpg")); + return preview; + } + /** * Adds new row to model * @param name String name of the face - * @param Path path to preview (if null than default preview is set) + * @param Path path to face */ public void addRowWithName(String name, Path path) { - if (!path.toFile().exists()) { - addRow(new Object[]{false, name, previewBasic}); + + Path preview = this.getPreviewPath(path); + int index = this.getRowCount() - filteredRows; + + if (preview == null || !preview.toFile().exists()) { + insertRow(index, new Object[]{false, name, previewBasic}); } else { try { - BufferedImage image = ImageIO.read(path.toFile()); + BufferedImage image = ImageIO.read(preview.toFile()); // Scale image to fit into column BufferedImage scaledImage = Scalr.resize(image, 70, 55); - addRow(new Object[]{false, name, new ImageIcon(scaledImage)}); + insertRow(index, new Object[]{false, name, new ImageIcon(scaledImage)}); } catch (IOException ex) { Exceptions.printStackTrace(ex); - } - + } } } - - /* - * - public void sortAlphabeticaly() { - List<String> rows = new ArrayList(); - for (int i = 0; i < getRowCount(); i++) { - rows.add(getValueAt(i, 1).toString()); - } - Collections.sort(rows); - } - */ - } diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form index 0f6af971885bde13eb07344ab6b7667233e28dd3..e535c924971aec99b66320669b3b8c1dd00cb72f 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form @@ -19,24 +19,26 @@ <Group type="102" alignment="0" attributes="0"> <EmptySpace min="-2" pref="41" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> - <Component id="tablePanel" alignment="1" min="-2" max="-2" attributes="0"/> - <Component id="buttonsPanel" min="-2" pref="969" max="-2" attributes="0"/> + <Component id="buttonsPanel" pref="1025" max="32767" attributes="0"/> + <Component id="tableScrollPane" max="32767" attributes="0"/> </Group> - <EmptySpace min="-2" pref="4" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> - <Group type="103" alignment="1" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="78" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="50" max="-2" attributes="0"/> <Component id="newProjectButton" min="-2" max="-2" attributes="0"/> </Group> - <Component id="openProjectButton" alignment="1" min="-2" max="-2" attributes="0"/> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/> + </Group> </Group> <Group type="102" alignment="1" attributes="0"> - <EmptySpace min="-2" pref="78" max="-2" attributes="0"/> - <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="openProjectButton" min="-2" max="-2" attributes="0"/> </Group> </Group> - <EmptySpace max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> </Group> </Group> </DimensionLayout> @@ -44,25 +46,22 @@ <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" attributes="0"> - <EmptySpace min="-2" pref="23" max="-2" attributes="0"/> - <Component id="newProjectButton" min="-2" max="-2" attributes="0"/> - </Group> - <Group type="102" alignment="1" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Component id="buttonsPanel" min="-2" pref="56" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/> - <Component id="buttonsPanel" max="-2" attributes="0"/> + <Component id="tableScrollPane" pref="768" max="32767" attributes="0"/> </Group> - </Group> - <EmptySpace max="-2" attributes="0"/> - <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="61" max="-2" attributes="0"/> + <Component id="newProjectButton" min="-2" max="-2" attributes="0"/> + <EmptySpace type="separate" max="-2" attributes="0"/> <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/> <Component id="openProjectButton" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> </Group> - <Component id="tablePanel" min="-2" max="-2" attributes="0"/> </Group> - <EmptySpace max="32767" attributes="0"/> + <EmptySpace pref="12" max="32767" attributes="0"/> </Group> </Group> </DimensionLayout> @@ -90,13 +89,16 @@ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.addButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="addButtonMouseClicked"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="20" ipadY="0" insetsTop="16" insetsLeft="0" insetsBottom="13" insetsRight="8" anchor="13" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="5" insetsRight="15" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -108,13 +110,16 @@ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.removeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="removeButtonMouseClicked"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="5" insetsRight="15" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -126,13 +131,16 @@ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="selectAllButtonMouseClicked"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="5" insetsRight="15" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -144,13 +152,16 @@ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="deselectAllButtonMouseClicked"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="5" insetsRight="15" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -163,13 +174,16 @@ <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.inflateButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> <Property name="alignmentX" type="float" value="0.5"/> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="inflateButtonMouseClicked"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="5" insetsRight="15" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -181,13 +195,16 @@ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.analyseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[100, 30]"/> + </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="analyseFaces"/> </Events> <Constraints> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="170" insetsBottom="13" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="100" insetsBottom="5" insetsRight="15" anchor="10" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -238,40 +255,16 @@ <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="newProjectButtonMouseClicked"/> </Events> </Component> - <Container class="javax.swing.JPanel" name="tablePanel"> - <Properties> - <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> - <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo"> - <EtchetBorder/> - </Border> - </Property> - </Properties> + <Container class="javax.swing.JScrollPane" name="tableScrollPane"> - <Layout> - <DimensionLayout dim="0"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="965" max="32767" attributes="0"/> - <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> - <Component id="table" alignment="0" pref="965" max="32767" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - <DimensionLayout dim="1"> - <Group type="103" groupAlignment="0" attributes="0"> - <EmptySpace min="0" pref="788" max="32767" attributes="0"/> - <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> - <Component id="table" alignment="0" pref="788" max="32767" attributes="0"/> - </Group> - </Group> - </DimensionLayout> - </Layout> + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> <Component class="javax.swing.JTable" name="table"> <Properties> <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor" postCode="table.getTableHeader().setOpaque(false);
table.getTableHeader().setBackground(new java.awt.Color(204,204,204));
table.getTableHeader().setFont(new java.awt.Font("Tahoma", 0, 18));
model.addTableModelListener(new TableModelListener() {
 public void tableChanged(TableModelEvent e) {
 jTable1TableChanged(e);
 }
});"> <Font name="Tahoma" size="18" style="0"/> </Property> - <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor" postCode="table.getColumnModel().getColumn(0).setMaxWidth(50);
table.getColumnModel().getColumn(2).setMaxWidth(85);
table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50);
table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(75);"> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor" postCode="table.getColumnModel().getColumn(0).setMaxWidth(50);
table.getColumnModel().getColumn(2).setMaxWidth(75);
table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50);
table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(85);"> <Connection code="model" type="code"/> </Property> <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> @@ -291,7 +284,7 @@ <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseClicked"/> </Events> <AuxValues> - <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="table.setSize(tablePanel.getWidth(), tablePanel.getHeight());"/> + <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="table.setSize(tableScrollPane.getWidth(), tableScrollPane.getHeight());"/> </AuxValues> </Component> </SubComponents> diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java index 6b3cd725fd6ea107dc64a4b6040116bf18085257..e9e58496e18c7ae2177227a14162c8c79579d759 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java @@ -1,10 +1,12 @@ package cz.fidentis.analyst.project; +import cz.fidentis.analyst.faceState.FaceStatePanel; import com.fasterxml.jackson.databind.ObjectMapper; import cz.fidentis.analyst.Project; import cz.fidentis.analyst.ProjectConfiguration; import cz.fidentis.analyst.core.FaceTab; import cz.fidentis.analyst.face.HumanFace; +import cz.fidentis.analyst.filter.FilterPanel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; @@ -21,6 +23,7 @@ import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JTable; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.filechooser.FileNameExtensionFilter; @@ -37,7 +40,7 @@ public class ProjectPanel extends JPanel { private List<FaceTab> tabs = new ArrayList<>(); - private ModelsTableModel model = new ModelsTableModel(new Object[]{"", "Models", "Preview"}, 0); + private ModelsTableModel model = new ModelsTableModel(); /* List of indexes of selected Rows */ private List<Integer> selectedRows = new ArrayList<>(); @@ -47,9 +50,8 @@ public class ProjectPanel extends JPanel { private Preferences userPreferences = Preferences.userNodeForPackage(Project.class); private FaceStatePanel faceStatePanel; - private FilterPanel filterPanel; - + /** * Creates new form ProjectPanel */ @@ -80,7 +82,7 @@ public class ProjectPanel extends JPanel { saveProjectButton = new javax.swing.JButton(); openProjectButton = new javax.swing.JButton(); newProjectButton = new javax.swing.JButton(); - tablePanel = new javax.swing.JPanel(); + tableScrollPane = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); buttonsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); @@ -89,6 +91,7 @@ public class ProjectPanel extends JPanel { addButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.addButton.text")); // NOI18N + addButton.setPreferredSize(new java.awt.Dimension(100, 30)); addButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { addButtonMouseClicked(evt); @@ -97,13 +100,13 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; - gridBagConstraints.ipadx = 20; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.insets = new java.awt.Insets(16, 0, 13, 8); + gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 15); buttonsPanel.add(addButton, gridBagConstraints); removeButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.removeButton.text")); // NOI18N + removeButton.setPreferredSize(new java.awt.Dimension(100, 30)); removeButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { removeButtonMouseClicked(evt); @@ -112,12 +115,13 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 22, 13, 8); + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 15); buttonsPanel.add(removeButton, gridBagConstraints); selectAllButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.selectAllButton.text")); // NOI18N + selectAllButton.setPreferredSize(new java.awt.Dimension(100, 30)); selectAllButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { selectAllButtonMouseClicked(evt); @@ -126,12 +130,13 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 22, 13, 8); + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 15); buttonsPanel.add(selectAllButton, gridBagConstraints); deselectAllButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.deselectAllButton.text")); // NOI18N + deselectAllButton.setPreferredSize(new java.awt.Dimension(100, 30)); deselectAllButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { deselectAllButtonMouseClicked(evt); @@ -140,13 +145,14 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 22, 13, 8); + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 15); buttonsPanel.add(deselectAllButton, gridBagConstraints); inflateButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(inflateButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.inflateButton.text")); // NOI18N inflateButton.setAlignmentX(0.5F); + inflateButton.setPreferredSize(new java.awt.Dimension(100, 30)); inflateButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { inflateButtonMouseClicked(evt); @@ -155,12 +161,13 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 4; gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 22, 13, 8); + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(5, 15, 5, 15); buttonsPanel.add(inflateButton, gridBagConstraints); analyseButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(analyseButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.analyseButton.text")); // NOI18N + analyseButton.setPreferredSize(new java.awt.Dimension(100, 30)); analyseButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { analyseFaces(evt); @@ -169,7 +176,7 @@ public class ProjectPanel extends JPanel { gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 5; gridBagConstraints.gridy = 0; - gridBagConstraints.insets = new java.awt.Insets(16, 170, 13, 4); + gridBagConstraints.insets = new java.awt.Insets(5, 100, 5, 15); buttonsPanel.add(analyseButton, gridBagConstraints); saveProjectButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N @@ -198,9 +205,7 @@ public class ProjectPanel extends JPanel { } }); - tablePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - - table.setSize(tablePanel.getWidth(), tablePanel.getHeight()); + table.setSize(tableScrollPane.getWidth(), tableScrollPane.getHeight()); table.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N table.getTableHeader().setOpaque(false); table.getTableHeader().setBackground(new java.awt.Color(204,204,204)); @@ -212,9 +217,9 @@ public class ProjectPanel extends JPanel { }); table.setModel(model); table.getColumnModel().getColumn(0).setMaxWidth(50); - table.getColumnModel().getColumn(2).setMaxWidth(85); + table.getColumnModel().getColumn(2).setMaxWidth(75); table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50); - table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(75); + table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(85); table.setDragEnabled(true); table.setRowHeight(60); table.setSelectionBackground(new java.awt.Color(102, 204, 255)); @@ -225,21 +230,7 @@ public class ProjectPanel extends JPanel { tableMouseClicked(evt); } }); - - javax.swing.GroupLayout tablePanelLayout = new javax.swing.GroupLayout(tablePanel); - tablePanel.setLayout(tablePanelLayout); - tablePanelLayout.setHorizontalGroup( - tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 965, Short.MAX_VALUE) - .addGroup(tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(table, javax.swing.GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE)) - ); - tablePanelLayout.setVerticalGroup( - tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 788, Short.MAX_VALUE) - .addGroup(tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(table, javax.swing.GroupLayout.DEFAULT_SIZE, 788, Short.MAX_VALUE)) - ); + tableScrollPane.setViewportView(table); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -248,45 +239,65 @@ public class ProjectPanel extends JPanel { .addGroup(layout.createSequentialGroup() .addGap(41, 41, 41) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tablePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 969, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(4, 4, 4) + .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1025, Short.MAX_VALUE) + .addComponent(tableScrollPane)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(78, 78, 78) + .addGap(50, 50, 50) .addComponent(newProjectButton)) - .addComponent(openProjectButton, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(saveProjectButton))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(78, 78, 78) - .addComponent(saveProjectButton))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(openProjectButton))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(23, 23, 23) - .addComponent(newProjectButton)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 768, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() + .addGap(61, 61, 61) + .addComponent(newProjectButton) + .addGap(18, 18, 18) .addComponent(saveProjectButton) .addGap(18, 18, 18) - .addComponent(openProjectButton)) - .addComponent(tablePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(openProjectButton) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap(12, Short.MAX_VALUE)) ); }// </editor-fold>//GEN-END:initComponents + public Project getProject() { + return project; + } + + public ModelsTableModel getModel() { + return model; + } + + public List<Integer> getSelectedRows() { + return selectedRows; + } + + public JTable getTable() { + return table; + } + + public void setSelectedRows(List<Integer> selectedRows) { + this.selectedRows = selectedRows; + } + public void setFaceStatePanel(FaceStatePanel faceStatePanel) { this.faceStatePanel = faceStatePanel; } - + public void setFilterPanel(FilterPanel filterPanel) { this.filterPanel = filterPanel; } @@ -317,6 +328,13 @@ public class ProjectPanel extends JPanel { } else { if (evt.getClickCount() == 2) { deselectAllRows(); + + // if cell is not editable, that means that row is being filtered + // and new face tab analysis shouldn't be opened + if (!model.isCellEditable(table.getSelectedRow(), 0)) { + return; + } + model.setValueAt(true, table.getSelectedRow(), 0); analyseSingleFace(); } @@ -380,14 +398,7 @@ public class ProjectPanel extends JPanel { } private void inflateButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_inflateButtonMouseClicked - - for (int i = 0; i < model.getRowCount(); i++) { - if (model.getValueAt(i, 0) == (Object) true) { - model.setValueAt(false, i, 0); - } else { - model.setValueAt(true, i, 0); - } - } + model.inflateSelection(); }//GEN-LAST:event_inflateButtonMouseClicked private void deselectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_deselectAllButtonMouseClicked @@ -395,9 +406,7 @@ public class ProjectPanel extends JPanel { }//GEN-LAST:event_deselectAllButtonMouseClicked private void selectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_selectAllButtonMouseClicked - for (int i = 0; i < model.getRowCount(); i++) { - model.setValueAt(true, i, 0); - } + model.setAllRowsSelection(true); }//GEN-LAST:event_selectAllButtonMouseClicked private void removeButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_removeButtonMouseClicked @@ -438,6 +447,7 @@ public class ProjectPanel extends JPanel { selectedRows.forEach(row -> { String name = model.getValueAt(row, 1).toString(); List<FaceTab> tabsToClose = new ArrayList<>(); + tabs.stream().filter(t -> (t.hasFace(name))).forEachOrdered(t -> { tabsToClose.add(t); }); @@ -446,20 +456,25 @@ public class ProjectPanel extends JPanel { tabsToClose.remove(0).close(); } + // Remove already loaded and stored face info faceStatePanel.removeFaceByName(name); + + // Remove face from filter history if row is currently filtered + if (row >= model.getRowCount() - filterPanel.getFilterHistory().getTotalFaces()) { + filterPanel.getFilterHistory().removeFilteredFace(name); + } + model.removeRow(row); + project.getCfg().removePath(name); }); selectedRows.clear(); } /** * Deselects all rows - * TODO : deselect only rows which are selected (checking row by row is slow) */ - private void deselectAllRows() { - for (int i = 0; i < model.getRowCount(); i++) { - model.setValueAt(false, i, 0); - } + public void deselectAllRows() { + model.setAllRowsSelection(false); } /** @@ -520,9 +535,7 @@ public class ProjectPanel extends JPanel { if (project.addNewPath(path)) { - Path preview = Paths.get(path.toString().split(".obj")[0] + "_preview.jpg"); - model.addRowWithName(name, preview); - filterPanel.checkAllFacesLoaded(false); + model.addRowWithName(name, path); } else { JOptionPane.showMessageDialog(this, @@ -649,57 +662,10 @@ public class ProjectPanel extends JPanel { * @param faceName String name of face * @param selected Boolean true if some face is selected from list, false otherwise */ - private void checkFaceState(String faceName, boolean selected) { + public void checkFaceState(String faceName, boolean selected) { Path path = project.getCfg().getPathToFaceByName(faceName); faceStatePanel.newSelection(selected, faceName, path); - } - - /** - * Sorts faces by alphabet - */ - private void alphabeticalFilter() { - this.deselectAllRows(); - /* - TableRowSorter<TableModel> sorter = new TableRowSorter<>(model); - jTable1.setRowSorter(sorter); - - List<RowSorter.SortKey> sortKeys = new ArrayList<>(); - sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING)); - sorter.setSortKeys(sortKeys);*/ - - List<String> names = new ArrayList(); - while (model.getRowCount() > 0) { - names.add(model.getValueAt(0, 1).toString()); - model.removeRow(0); - } - Collections.sort(names); - names.forEach(name -> { - - HumanFace face = project.loadFace(name); - Path preview = Paths.get(face.getPath().split(".obj")[0] + "_preview.jpg"); - model.addRowWithName(name, preview); - }); - - } - - /** - * Removes faces from project (and table of faces) based on filter configuration - */ - public void applyFilter(boolean isFeaturePointsFilter, boolean isKdTreeFilter, boolean isAlphaBeticalFilter) { - deselectAllRows(); - - for (int i = 0; i < model.getRowCount(); i++) { - HumanFace face = project.loadFace(model.getValueAt(i, 1).toString()); - - if ((isKdTreeFilter && !face.hasKdTree()) || (isFeaturePointsFilter && !face.hasFeaturePoints())) { - model.setValueAt(true, i, 0); - } - } - removeSelectedFaces(); - - if (isAlphaBeticalFilter) { - alphabeticalFilter(); - } + this.repaint(); } /** @@ -741,6 +707,7 @@ public class ProjectPanel extends JPanel { tabs.get(0).close(); } faceStatePanel.clearLoadedFaces(); + filterPanel.clearFiltering(); model.setRowCount(0); checkFaceState(null, false); selectedRows.clear(); @@ -832,7 +799,6 @@ public class ProjectPanel extends JPanel { "Loading project failed", JOptionPane.ERROR_MESSAGE); } - } } @@ -903,28 +869,19 @@ public class ProjectPanel extends JPanel { */ public void loadCurrentlySelectedFace() { + if (table.getSelectedRow() == -1) { + JOptionPane.showMessageDialog(faceStatePanel, + "None model selected", + "Select model", + JOptionPane.WARNING_MESSAGE); + return; + } String name = table.getValueAt(table.getSelectedRow(), 1).toString(); HumanFace face = project.loadFace(name); faceStatePanel.loadFaceGeometryInfo(face); checkFaceState(name, true); } - - /** - * Loads all faces from list to project - */ - public void loadAllFaces() { - for (int i = 0; i < model.getRowCount(); i++) { - - String name = model.getValueAt(i, 1).toString(); - project.loadFace(name); - - } - - filterPanel.checkAllFacesLoaded(true); - - } - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addButton; private javax.swing.JButton analyseButton; @@ -937,6 +894,6 @@ public class ProjectPanel extends JPanel { private javax.swing.JButton saveProjectButton; private javax.swing.JButton selectAllButton; private javax.swing.JTable table; - private javax.swing.JPanel tablePanel; + private javax.swing.JScrollPane tableScrollPane; // End of variables declaration//GEN-END:variables } diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java index ad98c996f180e8c9c8ce659a3da2fbb14fbf3b98..978760326fcf5d1d378a9c6f6b848cf43215b59d 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java @@ -1,5 +1,7 @@ package cz.fidentis.analyst.project; +import cz.fidentis.analyst.filter.FilterPanel; +import cz.fidentis.analyst.faceState.FaceStatePanel; import cz.fidentis.analyst.core.ControlPanel; import cz.fidentis.analyst.core.OutputWindowThread; import cz.fidentis.analyst.core.TopControlPanel; @@ -48,9 +50,11 @@ public final class ProjectTopComp extends TopComponent { private final ProjectPanel projectPanel; private final TopControlPanel controlPanel; - private final JScrollPane projectPanelScrollPane; + //private final JScrollPane projectPanelScrollPane; private final JScrollPane controlPanelScrollPane; + public static final int CONTROL_PANEL_TAB_POSITION_FILTER_PANEL = 1; + /** * Project Top Component */ @@ -64,12 +68,10 @@ public final class ProjectTopComp extends TopComponent { projectPanel = new ProjectPanel(); controlPanel = new TopControlPanel(); - projectPanelScrollPane = new JScrollPane(projectPanel); controlPanelScrollPane = new JScrollPane(controlPanel); initComponents(); - OutputWindowThread.execute(); // Face State Panel @@ -85,21 +87,14 @@ public final class ProjectTopComp extends TopComponent { projectPanel.setFaceStatePanel(facePanel); // Filter Panel + FilterPanel filterPanel = new FilterPanel(projectPanel); - // Listener for loading all faces - to enable filtering - ActionListener listenerLoadAllFaces = (ActionEvent e) -> { - projectPanel.loadAllFaces(); + ActionListener listenerChangeIcon = (ActionEvent e) -> { + this.controlPanel.setIconAt(CONTROL_PANEL_TAB_POSITION_FILTER_PANEL, filterPanel.getIcon()); }; - FilterPanel filterPanel = new FilterPanel(listenerLoadAllFaces); + filterPanel.setListenerChangeIcon(listenerChangeIcon); this.controlPanel.addTab(filterPanel.getName(), filterPanel.getIcon(), filterPanel); - - // Listener for applying filter on faces - ActionListener listenerFilter = (ActionEvent e) -> { - projectPanel.applyFilter(filterPanel.isFeaturePointsFilter(), filterPanel.isKdTreeFilter(), filterPanel.isAlphabeticalFilter()); - }; - - filterPanel.setFilterActionListener(listenerFilter); projectPanel.setFilterPanel(filterPanel); this.openAtTabPosition(0); @@ -111,6 +106,7 @@ public final class ProjectTopComp extends TopComponent { // Pass this class to installer so it can call method of this class on close Installer inst = new Installer(this); + this.repaint(); } private void initComponents() { @@ -120,7 +116,7 @@ public final class ProjectTopComp extends TopComponent { layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(projectPanelScrollPane, GroupLayout.DEFAULT_SIZE, 651, Short.MAX_VALUE) + .addComponent(projectPanel, GroupLayout.DEFAULT_SIZE, 651, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) // .addComponent(renderingToolBar, GroupLayout.PREFERRED_SIZE, RenderingToolBar.WIDTH, GroupLayout.PREFERRED_SIZE) .addComponent( @@ -135,7 +131,7 @@ public final class ProjectTopComp extends TopComponent { layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createBaselineGroup(true, true) - .addComponent(projectPanelScrollPane) + .addComponent(projectPanel) // .addComponent(renderingToolBar) .addComponent(controlPanelScrollPane) )) @@ -151,7 +147,7 @@ public final class ProjectTopComp extends TopComponent { public void componentClosed() { // TODO add custom code on component closing } - + void writeProperties(java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles diff --git a/GUI/src/main/resources/cz/fidentis/analyst/faceState/Bundle.properties b/GUI/src/main/resources/cz/fidentis/analyst/faceState/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..fc7efedd911e6298f091a06e471ab5d4e3cec416 --- /dev/null +++ b/GUI/src/main/resources/cz/fidentis/analyst/faceState/Bundle.properties @@ -0,0 +1,25 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +FaceStatePanel.geometryPanel.border.title=Geometry info +FaceStatePanel.filePanel.AccessibleContext.accessibleName=File info +FaceStatePanel.filePanel.border.title=File info +FaceStatePanel.textureOutput.text= +FaceStatePanel.photo.text= +FaceStatePanel.textureLabel.text=Texture File : +FaceStatePanel.photoPanel.border.title=Photo +FaceStatePanel.previewOutput.text= +FaceStatePanel.loadInfoButton.text=(Re)Load info +FaceStatePanel.previewLabel.text=Preview File : +FaceStatePanel.featurePointsOutput.text= +FaceStatePanel.fpLabel.text=Feature points : +FaceStatePanel.featurePointsLabel.text=Feature Points File : +FaceStatePanel.facetsOutput.text= +FaceStatePanel.sizeOutput.text= +FaceStatePanel.facetsLabel.text=Number of facets : +FaceStatePanel.sizeLabel.text=Size : +FaceStatePanel.verticesOutput.text= +FaceStatePanel.pathOutput.text= +FaceStatePanel.verticesLabel.text=Number of vertices : +FaceStatePanel.pathLabel.text=Path : diff --git a/GUI/src/main/resources/cz/fidentis/analyst/filter/Bundle.properties b/GUI/src/main/resources/cz/fidentis/analyst/filter/Bundle.properties new file mode 100644 index 0000000000000000000000000000000000000000..e64ceb4d8d7781318129b7b8ddf89804ebbc83af --- /dev/null +++ b/GUI/src/main/resources/cz/fidentis/analyst/filter/Bundle.properties @@ -0,0 +1,18 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. + +FilterPanel.filterPanel.border.title=Filter settings +FilterPanel.featurePointsPanel.border.title=Feature points +FilterPanel.applyFilterButton.text=Apply filter +FilterPanel.hasNotFPCheckbox.text=has not feature points +FilterPanel.hasFPCheckbox.text=has some feature point +FilterPanel.byFPLabel.text=By feature points +FilterPanel.byNameLabel.text=By name +FilterPanel.hasTextCheckbox.text=has text +FilterPanel.hasTextTextfield.text= +FilterPanel.hasNotTextCheckbox.text=has not text +FilterPanel.hasNotTextTextfield.text= +FilterPanel.hasSelectedFPCheckbox.text=has selected feature points +FilterPanel.clearFilteringButton.text=Clear filtering +FilterPanel.revertLastFilteringButton.text=Revert diff --git a/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties b/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties index 19ed0260e88c6efd3f19883f13ce5cf7f04155cf..1fbfa25613de326400342b4511bcc25ed36e5402 100644 --- a/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties +++ b/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties @@ -4,16 +4,6 @@ FaceStatePanel.pathLabel.text=Path : FaceStatePanel.sizeLabel.text=Size : FaceStatePanel.pathOutput.text= FaceStatePanel.sizeOutput.text= -FaceStatePanel.photoPanel.border.title=Photo -FaceStatePanel.photo.text= -FilterPanel.filterPanel.border.title=Filter settings -FilterPanel.hasFP.text=has feature points -FilterPanel.hasKD.text=has kd-tree -FilterPanel.alphabetical.text=alphabetical -FilterPanel.applyFilterButton.text=Apply filter -FilterPanel.warningLabel.text= -FilterPanel.faceNotLoadedLabel.text=All models must be loaded for filtering -FilterPanel.loadAllModelsButton.text=Load all models ProjectPanel.newProjectButton.text= ProjectPanel.openProjectButton.text= ProjectPanel.saveProjectButton.text= @@ -23,22 +13,4 @@ ProjectPanel.deselectAllButton.text=Deselect all ProjectPanel.selectAllButton.text=Select all ProjectPanel.removeButton.text=Remove ProjectPanel.addButton.text=Add -FaceStatePanel.geometryPanel.border.title=Geometry info -FaceStatePanel.verticesLabel.text=Number of vertices : -FaceStatePanel.facetsLabel.text=Number of facets : -FaceStatePanel.fpLabel.text=Feature points : -FaceStatePanel.verticesOutput.text= -FaceStatePanel.facetsOutput.text= -FaceStatePanel.textureOutput.text= -FaceStatePanel.previewOutput.text= -FaceStatePanel.featurePointsOutput.text= -FaceStatePanel.textureLabel.text=Texture File : -FaceStatePanel.previewLabel.text=Preview File : -FaceStatePanel.featurePointsLabel.text=Feature Points File : -FaceStatePanel.sizeOutput.text= -FaceStatePanel.pathOutput.text= -FaceStatePanel.sizeLabel.text=Size : -FaceStatePanel.pathLabel.text=Path : -FaceStatePanel.filePanel.AccessibleContext.accessibleName=File info -FaceStatePanel.filePanel.border.title=File info -FaceStatePanel.loadInfoButton.text=(Re)Load info +FilterPanel.nameTextField.text= diff --git a/GUI/src/main/resources/face_gray32x32.png b/GUI/src/main/resources/face_gray32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..12b466ff255fbe1b6972a354277c765ebbb8ed21 Binary files /dev/null and b/GUI/src/main/resources/face_gray32x32.png differ diff --git a/GUI/src/main/resources/filter28x28.png b/GUI/src/main/resources/filter_off28x28.png similarity index 100% rename from GUI/src/main/resources/filter28x28.png rename to GUI/src/main/resources/filter_off28x28.png diff --git a/GUI/src/main/resources/filter_on28x28.png b/GUI/src/main/resources/filter_on28x28.png new file mode 100644 index 0000000000000000000000000000000000000000..4783708d132c092688ea812680c95198b2b7e3a0 Binary files /dev/null and b/GUI/src/main/resources/filter_on28x28.png differ