diff --git a/Comparison/src/main/java/cz/fidentis/analyst/Project.java b/Comparison/src/main/java/cz/fidentis/analyst/Project.java index 14db43ce62bcd139a4035882e7677a779d31ec31..ffcf7cfa5eb69eb99007f00411e244486bc58b3b 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/Project.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/Project.java @@ -4,7 +4,6 @@ import cz.fidentis.analyst.face.HumanFace; 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.Collections; import java.util.List; @@ -219,10 +218,7 @@ public class Project { Path path = this.getCfg().getPathToFaceByName(name); File file = path.toFile(); face = new HumanFace(file, true); // loads also landmarks, if exist - - String pathString = path.toString(); - Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg")); - //Path previewSmall = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview_small.png")); + Path preview = path.resolveSibling(name.concat("_preview.jpg")); face.setPreview(preview); this.addFace(face); out.printDuration("Loaded model " + face.getShortName() +" with " + face.getMeshModel().getNumVertices() + " vertices"); diff --git a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java index 3f42efb68bfb2ecc7de4d64dc101d7307a9a745e..c9e9e711f60c7849684c0066d52248970d64c5e4 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java @@ -81,7 +81,9 @@ public class ProjectConfiguration { List<File> f = new ArrayList<>(); paths.forEach(p -> { - f.add(p.toFile()); + if (p.toFile().exists()) { + f.add(p.toFile()); + } }); return f; diff --git a/GUI/src/main/java/cz/fidentis/analyst/gui/Installer.java b/GUI/src/main/java/cz/fidentis/analyst/gui/Installer.java index 3204b823d48438da5912bb865a9f94b6ab09ce55..cb50c9a7a8baa92590d8d0f7d6f4d215d93d605e 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/gui/Installer.java +++ b/GUI/src/main/java/cz/fidentis/analyst/gui/Installer.java @@ -1,5 +1,6 @@ package cz.fidentis.analyst.gui; +import cz.fidentis.analyst.project.ProjectTopComp; import javax.swing.JOptionPane; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; @@ -11,7 +12,24 @@ import org.openide.modules.ModuleInstall; * @author Radek Oslejsek */ public class Installer extends ModuleInstall { - + + private ProjectTopComp projectTopComp; + + /** + * Constructor with projectTopComp + * @param projectTopComp ProjectTopComp + */ + public Installer(ProjectTopComp projectTopComp) { + this.projectTopComp = projectTopComp; + } + + /** + * Default constructor + */ + public Installer() { + //super(); + } + @Override public void restored() { try { @@ -40,9 +58,14 @@ public class Installer extends ModuleInstall { @Override public boolean closing() { + + if (projectTopComp != null) { + projectTopComp.saveProjectOnClose(); + } + int answer = JOptionPane.showConfirmDialog(null, "Do you really want to close the application?", "", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - return answer == JOptionPane.YES_OPTION; + return answer == JOptionPane.YES_OPTION; } diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form index e7dae1ad568b1474ef15b4d8173ac644dc1ae2c6..99a03f523b182df9fae1d248b02ea3246e3bd90c 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form +++ b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form @@ -301,6 +301,9 @@ <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.photo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> </Property> </Properties> + <Events> + <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="photoMouseClicked"/> + </Events> </Component> </SubComponents> </Container> diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java index 814b860e9fd5ca1cc6bb3de94edcfc487134ca6c..1d0eb6d9525c1e22c2fc1767dde128f98b7369b1 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java @@ -2,7 +2,9 @@ package cz.fidentis.analyst.project; 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.io.IOException; import java.nio.file.Files; @@ -10,6 +12,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import javax.imageio.ImageIO; import javax.swing.ImageIcon; +import javax.swing.JOptionPane; /** * @@ -21,6 +24,7 @@ public class FaceStatePanel extends ControlPanel { private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png")); //private final ImageIcon warning = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "warning16x16.png")); private final ImageIcon anonymousFace = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face160x160.png")); + private ImageIcon previewFace = null; public static final String ICON = "head28x28.png"; public static final String NAME = "Face State"; @@ -175,6 +179,11 @@ public class FaceStatePanel extends ControlPanel { photo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face160x160.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(photo, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.photo.text")); // NOI18N + photo.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + photoMouseClicked(evt); + } + }); javax.swing.GroupLayout photoPanelLayout = new javax.swing.GroupLayout(photoPanel); photoPanel.setLayout(photoPanelLayout); @@ -219,6 +228,14 @@ public class FaceStatePanel extends ControlPanel { filePanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.filePanel.AccessibleContext.accessibleName")); // NOI18N }// </editor-fold>//GEN-END:initComponents + + private void photoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_photoMouseClicked + + if (previewFace != null) { + JOptionPane.showMessageDialog(this.getParent(), previewFace, "Preview Image", JOptionPane.PLAIN_MESSAGE); + } + + }//GEN-LAST:event_photoMouseClicked /** * Shows face information on panel @@ -250,11 +267,16 @@ public class FaceStatePanel extends ControlPanel { private ImageIcon getPhoto(HumanFace face, Path path) { ImageIcon image; + previewFace = null; + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); if (face != null) { if (face.getPreview() != null) { + previewFace = new ImageIcon(face.getPreview().getScaledInstance((int)screenSize.getWidth() - 100, (int)screenSize.getHeight() - 100, Image.SCALE_FAST)); + photo.setToolTipText("Click to enlarge the image"); return new ImageIcon(face.getPreview().getScaledInstance(240, 160, Image.SCALE_FAST)); } + photo.setToolTipText(""); return anonymousFace; } @@ -264,12 +286,16 @@ public class FaceStatePanel extends ControlPanel { Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg")); try { - image = new ImageIcon(ImageIO.read(preview.toFile()).getScaledInstance(240, 160, Image.SCALE_FAST)); + + 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)); + photo.setToolTipText("Click to enlarge the image"); return image; } catch (IOException ex) { //Exceptions.printStackTrace(ex);) } } + photo.setToolTipText(""); return anonymousFace; } 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 f6842bed8c44ba235a03f350054f6ad3714d3e0f..f11e510ff7541445b442531ec4d579346c6b6821 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" ?> -<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> +<Form version="1.9" 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"/> @@ -21,9 +21,9 @@ <Group type="103" groupAlignment="1" attributes="0"> <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/> <Group type="102" alignment="1" attributes="0"> - <Group type="103" groupAlignment="0" max="-2" attributes="0"> - <Component id="buttonsPanel" alignment="0" max="32767" attributes="0"/> - <Component id="faceTableScrollPanel" alignment="0" min="-2" pref="863" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" max="-2" attributes="0"> + <Component id="faceTableScrollPanel" pref="863" max="32767" attributes="0"/> + <Component id="buttonsPanel" max="32767" attributes="0"/> </Group> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> @@ -44,17 +44,17 @@ <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> - <EmptySpace min="-2" pref="12" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> - <Group type="102" alignment="0" attributes="0"> - <Component id="buttonsPanel" min="-2" max="-2" attributes="0"/> - <EmptySpace min="-2" pref="6" max="-2" 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"> - <Component id="newProjectButton" min="-2" max="-2" attributes="0"/> - <EmptySpace type="separate" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="buttonsPanel" max="-2" attributes="0"/> </Group> </Group> + <EmptySpace max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> <Component id="faceTableScrollPanel" min="-2" pref="768" max="-2" attributes="0"/> <Group type="102" alignment="0" attributes="0"> @@ -63,7 +63,7 @@ <Component id="openProjectButton" min="-2" max="-2" attributes="0"/> </Group> </Group> - <EmptySpace max="32767" attributes="0"/> + <EmptySpace pref="12" max="32767" attributes="0"/> </Group> </Group> </DimensionLayout> @@ -97,7 +97,7 @@ </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="16" insetsBottom="13" insetsRight="4" anchor="13" weightX="0.0" weightY="0.0"/> + <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="20" ipadY="0" insetsTop="16" insetsLeft="0" insetsBottom="13" insetsRight="4" anchor="13" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> @@ -174,43 +174,6 @@ </Constraint> </Constraints> </Component> - <Component class="javax.swing.JButton" name="oneOnOneButton"> - <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="ProjectPanel.oneOnOneButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - <Property name="alignmentX" type="float" value="0.5"/> - </Properties> - <Events> - <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="oneOnOneButtonMouseClicked"/> - </Events> - <Constraints> - <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> - <GridBagConstraints gridX="6" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> - <Component class="javax.swing.JButton" name="manyToManyButton"> - <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="ProjectPanel.manyToManyButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> - </Property> - </Properties> - <Events> - <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="manyToManyButtonMouseClicked"/> - </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="30" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/> - </Constraint> - </Constraints> - </Component> <Component class="javax.swing.JButton" name="analyseButton"> <Properties> <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor"> @@ -221,11 +184,11 @@ </Property> </Properties> <Events> - <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="analyseButtonMouseClicked"/> + <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="7" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" 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="16" insetsLeft="75" insetsBottom="13" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/> </Constraint> </Constraints> </Component> 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 0a6bddff7342f9bffbd003602fdc23af01b9253a..a9807f150ad30eca5c3e0f46aac8e693fc41be6f 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java @@ -14,6 +14,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.prefs.Preferences; import java.util.stream.Collectors; import javax.swing.AbstractAction; import javax.swing.ImageIcon; @@ -43,6 +44,8 @@ public class ProjectPanel extends JPanel { private ObjectMapper mapper = new ObjectMapper(); + private Preferences userPreferences = Preferences.userNodeForPackage(Project.class); + private FaceStatePanel faceStatePanel; private FilterPanel filterPanel; @@ -55,7 +58,6 @@ public class ProjectPanel extends JPanel { project = new Project(); initComponents(); - } /** @@ -74,8 +76,6 @@ public class ProjectPanel extends JPanel { selectAllButton = new javax.swing.JButton(); deselectAllButton = new javax.swing.JButton(); inflateButton = new javax.swing.JButton(); - oneOnOneButton = new javax.swing.JButton(); - manyToManyButton = new javax.swing.JButton(); analyseButton = new javax.swing.JButton(); faceTableScrollPanel = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); @@ -99,7 +99,7 @@ public class ProjectPanel extends JPanel { gridBagConstraints.gridy = 0; gridBagConstraints.ipadx = 20; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; - gridBagConstraints.insets = new java.awt.Insets(16, 16, 13, 4); + gridBagConstraints.insets = new java.awt.Insets(16, 0, 13, 4); buttonsPanel.add(addButton, gridBagConstraints); removeButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N @@ -159,46 +159,17 @@ public class ProjectPanel extends JPanel { gridBagConstraints.insets = new java.awt.Insets(16, 22, 13, 4); buttonsPanel.add(inflateButton, gridBagConstraints); - oneOnOneButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(oneOnOneButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.oneOnOneButton.text")); // NOI18N - oneOnOneButton.setAlignmentX(0.5F); - oneOnOneButton.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - oneOnOneButtonMouseClicked(evt); - } - }); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 6; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 11, 13, 4); - buttonsPanel.add(oneOnOneButton, gridBagConstraints); - - manyToManyButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(manyToManyButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.manyToManyButton.text")); // NOI18N - manyToManyButton.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - manyToManyButtonMouseClicked(evt); - } - }); - gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 5; - gridBagConstraints.gridy = 0; - gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new java.awt.Insets(16, 30, 13, 4); - buttonsPanel.add(manyToManyButton, 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.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { - analyseButtonMouseClicked(evt); + analyseFaces(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); - gridBagConstraints.gridx = 7; + gridBagConstraints.gridx = 5; gridBagConstraints.gridy = 0; - gridBagConstraints.insets = new java.awt.Insets(16, 11, 13, 4); + gridBagConstraints.insets = new java.awt.Insets(16, 75, 13, 4); buttonsPanel.add(analyseButton, gridBagConstraints); faceTableScrollPanel.setPreferredSize(new java.awt.Dimension(812, 750)); @@ -265,9 +236,9 @@ public class ProjectPanel extends JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(saveProjectButton) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 863, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 863, Short.MAX_VALUE) + .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(78, 78, 78) @@ -280,14 +251,14 @@ public class ProjectPanel extends JPanel { layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(12, 12, 12) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(6, 6, 6)) + .addGap(23, 23, 23) + .addComponent(newProjectButton)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(newProjectButton) - .addGap(18, 18, 18))) + .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(faceTableScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 768, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createSequentialGroup() @@ -333,69 +304,63 @@ public class ProjectPanel extends JPanel { if (evt.getClickCount() == 2) { deselectAllRows(); model.setValueAt(true, table.getSelectedRow(), 0); - analyseButtonMouseClicked(evt); + analyseSingleFace(); } checkFaceState(table.getValueAt(table.getSelectedRow(), 1).toString(), true); } }//GEN-LAST:event_tableMouseClicked - private void analyseButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_analyseButtonMouseClicked + /** + * Opens analysis of single selected face + */ + private void analyseSingleFace() { + + String name = model.getValueAt(selectedRows.get(0), 1).toString(); + HumanFace face = project.loadFace(name); - if (selectedRows.size() == 1) { + if (project.getFaceByName(name) == null) { + project.addFace(face); + } - String name = model.getValueAt(selectedRows.get(0), 1).toString(); - HumanFace face = project.loadFace(name); + createSingleFaceTab(face, name, false); + } + + /** + * Opens analysis of two selected faces - 1:1 + */ + private void analyseOneOnOneFaces() { + + String name1 = model.getValueAt(selectedRows.get(0), 1).toString(); + String name2 = model.getValueAt(selectedRows.get(1), 1).toString(); - if (project.getFaceByName(name) == null) { - project.addFace(face); - } - - - - createSingleFaceTab(face, name, false); - } else { - JOptionPane.showMessageDialog(this, "Select one model"); + HumanFace face1 = project.loadFace(name1); + HumanFace face2 = project.loadFace(name2); + + if (project.getFaceByName(name1) == null) { + project.addFace(face1); + } + + if (project.getFaceByName(name2) == null) { + project.addFace(face2); } - }//GEN-LAST:event_analyseButtonMouseClicked - private void manyToManyButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_manyToManyButtonMouseClicked + createFaceToFaceTab(face1, face2, name1 + ":" + name2, false); + } + + /** + * Opens analysis of N:N selected faces + */ + private void analyseManyToManyFaces() { + List<Path> faces = selectedRows.stream() .map(i -> model.getValueAt(selectedRows.get(i), 1).toString()) .map(s -> project.getCfg().getPathToFaceByName(s)) .collect(Collectors.toList()); - if (faces.size() > 2) { - createManyToManyTab("N:N", faces); - } else { - JOptionPane.showMessageDialog(this, "Select at least three models"); - } - }//GEN-LAST:event_manyToManyButtonMouseClicked - - private void oneOnOneButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_oneOnOneButtonMouseClicked - - if (selectedRows.size() == 2) { - - String name1 = model.getValueAt(selectedRows.get(0), 1).toString(); - String name2 = model.getValueAt(selectedRows.get(1), 1).toString(); - - HumanFace face1 = project.loadFace(name1); - HumanFace face2 = project.loadFace(name2); - - if (project.getFaceByName(name1) == null) { - project.addFace(face1); - } - - if (project.getFaceByName(name2) == null) { - project.addFace(face2); - } - - createFaceToFaceTab(face1, face2, name1 + ":" + name2, false); - } else { - JOptionPane.showMessageDialog(this, "Select two models"); - } - }//GEN-LAST:event_oneOnOneButtonMouseClicked - + createManyToManyTab("N:N", faces); + } + private void inflateButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_inflateButtonMouseClicked for (int i = 0; i < model.getRowCount(); i++) { @@ -424,6 +389,28 @@ public class ProjectPanel extends JPanel { private void addButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMouseClicked loadModel(false); }//GEN-LAST:event_addButtonMouseClicked + + private void analyseFaces(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_analyseFaces + + switch (selectedRows.size()) { + + case 0: + JOptionPane.showMessageDialog(this, "None faces selected"); + break; + + case 1: + analyseSingleFace(); + break; + + case 2: + analyseOneOnOneFaces(); + break; + + default: + analyseManyToManyFaces(); + break; + } + }//GEN-LAST:event_analyseFaces /** * Removes selected faces (those which are checked in check boxes) @@ -510,19 +497,20 @@ public class ProjectPanel extends JPanel { for (File file : files) { Path path = Paths.get(file.getAbsolutePath()); - String name = path.toString().substring(path.toString().lastIndexOf(File.separatorChar) + 1, path.toString().lastIndexOf('.')); + String name = path.toString().substring(path.toString() + .lastIndexOf(File.separatorChar) + 1, + path.toString().lastIndexOf('.')); if (project.addNewPath(path)) { - String pathString = path.toString(); - Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview_small.png")); - + Path preview = path.resolveSibling(name.concat("_preview_small.jpg")); model.addRowWithName(name, preview); - filterPanel.checkAllFacesLoaded(false); } else { - JOptionPane.showMessageDialog(this, String.format("Model with name %s is already loaded", name)); + JOptionPane.showMessageDialog(this, + String.format("Model %s is already loaded", + name)); } } } @@ -533,17 +521,25 @@ public class ProjectPanel extends JPanel { */ private void loadTabs() { + // Load Single face tabs project.getCfg().getSingleTabFaces().forEach(name -> { HumanFace face1 = project.loadFace(name); - createSingleFaceTab(face1, name, true); + if (face1 != null) { + createSingleFaceTab(face1, name, true); + } }); + // Load Face to face tabs project.getCfg().getFaceToFaceTabFaces().keySet().forEach(name -> { HumanFace face1 = project.loadFace(name); - project.getCfg().getFaceToFaceTabFaces().get(name).forEach(otherName -> { - HumanFace face2 = project.loadFace(otherName); - createFaceToFaceTab(face1, face2, name + ":" + otherName, true); - }); + if (face1 != null) { + project.getCfg().getFaceToFaceTabFaces().get(name).forEach(otherName -> { + HumanFace face2 = project.loadFace(otherName); + if (face2 != null) { + createFaceToFaceTab(face1, face2, name + ":" + otherName, true); + } + }); + } }); } @@ -556,6 +552,7 @@ public class ProjectPanel extends JPanel { * @return either loaded face from project or newly opened face from file */ private HumanFace getLoadedOrNewFace(String tabName, HumanFace face) { + for (FaceTab t : tabs) { if (t.hasFace(face.getShortName()) && !t.getName().equals(tabName)) { @@ -585,10 +582,11 @@ public class ProjectPanel extends JPanel { }; + // Check if face is already loaded in some other tab - if not, face + // is not open from path but loaded from project face = getLoadedOrNewFace(name, face); FaceTab newTab = new FaceTab(face, null, name, tabCloseListener); - if (!tabs.contains(newTab)) { tabs.add(newTab); if (!loadFromFile) { @@ -620,13 +618,14 @@ public class ProjectPanel extends JPanel { } }; + // Check if face is already loaded in some other tab - if not, face + // is not open from path but loaded from project face1 = getLoadedOrNewFace(nameOfTab, face1); face2 = getLoadedOrNewFace(nameOfTab, face2); FaceTab newTab = new FaceTab(face1, face2, nameOfTab, tabCloseListener); if (!tabs.contains(newTab)) { - tabs.add(newTab); if (!loadFromFile) { project.addNewFaceToFaceTabFace(face1.getShortName(), face2.getShortName()); @@ -728,21 +727,37 @@ public class ProjectPanel extends JPanel { * project */ public void openExistingOrNewProject() { + ImageIcon recentProjectImage = new ImageIcon(ProjectTopComp.class.getClassLoader().getResource("/" + "recent_project.png")); ImageIcon newProjectImage = new ImageIcon(ProjectTopComp.class.getClassLoader().getResource("/" + "new.png")); ImageIcon existingProjectImage = new ImageIcon(ProjectTopComp.class.getClassLoader().getResource("/" + "open.png")); - Object[] options = {newProjectImage, existingProjectImage}; + Object[] options = {recentProjectImage, newProjectImage, existingProjectImage}; + File recentProjectFile = getRecentProject(); + String recentProjectInfo; + if (recentProjectFile != null) { + recentProjectInfo = "\n\nMost recent project is : " + recentProjectFile.getAbsolutePath(); + } else { + recentProjectInfo = "\n\nCouldn't find most recent project"; + } int choice = JOptionPane.showOptionDialog(this, - "Would you like to create a new project or open an existing project?", + "Would you like to create a new project or open an existing project?" + + recentProjectInfo, "Select project", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, - options[0]); + options[1]); - if (choice == 1) { - openProject(); + switch (choice) { + case 0: + openRecentProject(); + break; + case 2: + openProject(); + break; + default: + break; } } @@ -805,39 +820,76 @@ public class ProjectPanel extends JPanel { try { mapper.writeValue(file, project.getCfg()); + userPreferences.put("pathToMostRecentProject", file.getAbsolutePath()); project.setSaved(true); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } - } + /** - * Opens project, which user selects in File Chooser + * Opens project from file + * @param f File */ - private void openProject() { + private void openProjectFromFile(File f) { - File f; - f = new FileChooserBuilder(ProjectTopComp.class) - .setTitle("Choose existing project") - .setDefaultWorkingDirectory(new File(System.getProperty("user.home"))) - .setFileFilter(new FileNameExtensionFilter("json files (*.json)", "json")) - .setAcceptAllFileFilterUsed(true) - .showOpenDialog(); - if (f != null) { try { resetProject(); project.setCfg(mapper.readValue(f, ProjectConfiguration.class)); loadModel(true); loadTabs(); + userPreferences.put("pathToMostRecentProject", f.getAbsolutePath()); project.setSaved(true); } catch (IOException ex) { - Exceptions.printStackTrace(ex); + //Exceptions.printStackTrace(ex); + JOptionPane.showMessageDialog(this, + "Couldn't load project", + "Loading project failed", + JOptionPane.ERROR_MESSAGE); } - } + } + } + + /** + * Opens most recent project (loads project from user preferences) + */ + private void openRecentProject() { + File f = getRecentProject(); + openProjectFromFile(f); + } + + /** + * Loads most recent project from user preferences + * @return File where project is saved, null if no project was found + */ + public File getRecentProject() { + + String path = userPreferences.get("pathToMostRecentProject", ""); + if (path.equals("")) { + return null; + } + Path f = Paths.get(path); + return f.toFile(); + } + + /** + * Opens project, which user selects in File Chooser + */ + private void openProject() { + + File f; + f = new FileChooserBuilder(ProjectTopComp.class) + .setTitle("Choose existing project") + .setDefaultWorkingDirectory(new File(System.getProperty("user.home"))) + .setFileFilter(new FileNameExtensionFilter("json files (*.json)", "json")) + .setAcceptAllFileFilterUsed(true) + .showOpenDialog(); + + openProjectFromFile(f); } /** @@ -923,9 +975,7 @@ public class ProjectPanel extends JPanel { private javax.swing.JButton deselectAllButton; private javax.swing.JScrollPane faceTableScrollPanel; private javax.swing.JButton inflateButton; - private javax.swing.JButton manyToManyButton; private javax.swing.JButton newProjectButton; - private javax.swing.JButton oneOnOneButton; private javax.swing.JButton openProjectButton; private javax.swing.JButton removeButton; private javax.swing.JButton saveProjectButton; 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 f9581d2e833f5933c5963a125cecacf4e9ed1513..06ae6879e7d23e8b12247f75312d4134590aaa93 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java +++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java @@ -3,9 +3,11 @@ package cz.fidentis.analyst.project; import cz.fidentis.analyst.core.ControlPanel; import cz.fidentis.analyst.core.OutputWindowThread; import cz.fidentis.analyst.core.TopControlPanel; +import cz.fidentis.analyst.gui.Installer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.GroupLayout; +import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.LayoutStyle; import org.netbeans.api.settings.ConvertAsProperties; @@ -107,6 +109,8 @@ public final class ProjectTopComp extends TopComponent { // Asks user whether he wants to create new project or open existing projectPanel.openExistingOrNewProject(); + // Pass this class to installer so it can call method of this class on close + Installer inst = new Installer(this); } private void initComponents() { @@ -160,9 +164,12 @@ public final class ProjectTopComp extends TopComponent { // TODO read your settings according to their version } - /* - @Override - public boolean canClose() { + + /** + * Checks whether currently opened project is saved or not and asks user + * whether he wants to save it or not on close + */ + public void saveProjectOnClose() { if (!projectPanel.isProjectSaved()) { int save = JOptionPane.showConfirmDialog(null, @@ -172,6 +179,5 @@ public final class ProjectTopComp extends TopComponent { projectPanel.saveProject(); } } - return super.canClose(); //To change body of generated methods, choose Tools | Templates. - }*/ + } } 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 0b7316a46801607e818342454ca75820476204b8..da9519e275e361caa36c4b237e5222b59301b43d 100644 --- a/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties +++ b/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties @@ -26,8 +26,6 @@ ProjectPanel.newProjectButton.text= ProjectPanel.openProjectButton.text= ProjectPanel.saveProjectButton.text= ProjectPanel.analyseButton.text=Analyse -ProjectPanel.manyToManyButton.text=N:N -ProjectPanel.oneOnOneButton.text=Open 1:1 ProjectPanel.inflateButton.text=Inflate ProjectPanel.deselectAllButton.text=Deselect all ProjectPanel.selectAllButton.text=Select all diff --git a/GUI/src/main/resources/recent_project.png b/GUI/src/main/resources/recent_project.png new file mode 100644 index 0000000000000000000000000000000000000000..bff1ad9403bf425ba13c3246a114ab287e04fbc4 Binary files /dev/null and b/GUI/src/main/resources/recent_project.png differ