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; 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; import java.util.prefs.Preferences; import java.util.stream.Collectors; import javax.swing.AbstractAction; 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; import org.openide.filesystems.FileChooserBuilder; import org.openide.util.Exceptions; /** * * @author Matej Kovar */ public class ProjectPanel extends JPanel { private Project project; private List<FaceTab> tabs = new ArrayList<>(); private ModelsTableModel model = new ModelsTableModel(); /* List of indexes of selected Rows */ private List<Integer> selectedRows = new ArrayList<>(); private ObjectMapper mapper = new ObjectMapper(); private Preferences userPreferences = Preferences.userNodeForPackage(Project.class); private FaceStatePanel faceStatePanel; private FilterPanel filterPanel; /** * Creates new form ProjectPanel */ public ProjectPanel() { project = new Project(); initComponents(); } /** * 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() { java.awt.GridBagConstraints gridBagConstraints; buttonsPanel = new javax.swing.JPanel(); addButton = new javax.swing.JButton(); removeButton = new javax.swing.JButton(); selectAllButton = new javax.swing.JButton(); deselectAllButton = new javax.swing.JButton(); inflateButton = new javax.swing.JButton(); analyseButton = new javax.swing.JButton(); saveProjectButton = new javax.swing.JButton(); openProjectButton = new javax.swing.JButton(); newProjectButton = new javax.swing.JButton(); tableScrollPane = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); buttonsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); buttonsPanel.setMinimumSize(new java.awt.Dimension(0, 0)); buttonsPanel.setLayout(new java.awt.GridBagLayout()); 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 0; 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 4; gridBagConstraints.gridy = 0; 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); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 5; gridBagConstraints.gridy = 0; gridBagConstraints.insets = new java.awt.Insets(5, 100, 5, 15); buttonsPanel.add(analyseButton, gridBagConstraints); saveProjectButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N saveProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/save100x24.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(saveProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.saveProjectButton.text")); // NOI18N saveProjectButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { saveProjectButtonMouseClicked(evt); } }); openProjectButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N openProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/open100x24.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(openProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.openProjectButton.text")); // NOI18N openProjectButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { openProjectButtonMouseClicked(evt); } }); newProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/new100x24.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(newProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.newProjectButton.text")); // NOI18N newProjectButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { newProjectButtonMouseClicked(evt); } }); 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)); table.getTableHeader().setFont(new java.awt.Font("Tahoma", 0, 18)); model.addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent e) { jTable1TableChanged(e); } }); table.setModel(model); 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); table.setDragEnabled(true); table.setRowHeight(60); table.setSelectionBackground(new java.awt.Color(102, 204, 255)); table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); table.getTableHeader().setReorderingAllowed(false); table.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { tableMouseClicked(evt); } }); tableScrollPane.setViewportView(table); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(41, 41, 41) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1025, Short.MAX_VALUE) .addComponent(tableScrollPane)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(50, 50, 50) .addComponent(newProjectButton)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(saveProjectButton))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .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() .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) .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; } public boolean isProjectSaved() { return project.isSaved(); } private void newProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_newProjectButtonMouseClicked if (loadNewProject()) { newProject(); } }//GEN-LAST:event_newProjectButtonMouseClicked private void openProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_openProjectButtonMouseClicked if (loadNewProject()) { openProject(); } }//GEN-LAST:event_openProjectButtonMouseClicked private void saveProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_saveProjectButtonMouseClicked saveProject(); }//GEN-LAST:event_saveProjectButtonMouseClicked private void tableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseClicked if (table.getSelectedRowCount() == 0) { checkFaceState(null, false); } 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(); } checkFaceState(table.getValueAt(table.getSelectedRow(), 1).toString(), true); } }//GEN-LAST:event_tableMouseClicked /** * Opens analysis of single selected face */ private void analyseSingleFace() { 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(); HumanFace face1 = project.loadFace(name1); HumanFace face2 = project.loadFace(name2); Object[] options = {face1.getShortName(), face2.getShortName()}; int choice = JOptionPane.showOptionDialog(this, "Faces: ", "Select primary face", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (choice == 0) { createFaceToFaceTab(face1, face2, name1 + ":" + name2, false); } else { createFaceToFaceTab(face2, face1, name2 + ":" + name1, false); } } /** * Opens analysis of N:N selected faces */ private void analyseManyToManyFaces() { List<Path> faces = selectedRows.stream() .map(i -> model.getValueAt(i, 1).toString()) .map(s -> project.getCfg().getPathToFaceByName(s)) .collect(Collectors.toList()); createManyToManyTab("N:N", faces); } private void inflateButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_inflateButtonMouseClicked model.inflateSelection(); }//GEN-LAST:event_inflateButtonMouseClicked private void deselectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_deselectAllButtonMouseClicked deselectAllRows(); }//GEN-LAST:event_deselectAllButtonMouseClicked private void selectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_selectAllButtonMouseClicked model.setAllRowsSelection(true); }//GEN-LAST:event_selectAllButtonMouseClicked private void removeButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_removeButtonMouseClicked removeSelectedFaces(); }//GEN-LAST:event_removeButtonMouseClicked 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) */ private void removeSelectedFaces() { Collections.sort(selectedRows, Collections.reverseOrder()); 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); }); while(!tabsToClose.isEmpty()) { 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 */ public void deselectAllRows() { model.setAllRowsSelection(false); } /** * Updates selectedRows - adds new selected rows or removes deselected rows * @param e TableModelEvent */ private void jTable1TableChanged(TableModelEvent e) { if (e.getType() == javax.swing.event.TableModelEvent.UPDATE) { int row = e.getFirstRow(); if (table.getValueAt(row, 0) == (Object)true) { if (!selectedRows.contains(row)) { selectedRows.add(row); } } else { if (selectedRows.contains(row)) { selectedRows.remove((Integer)row); } } } else if (e.getType() == javax.swing.event.TableModelEvent.INSERT || e.getType() == javax.swing.event.TableModelEvent.DELETE) { project.setSaved(false); } } /** * Loads model selected in file chooser by user * @param loadFromFile true if models are loaded from file, else user chooses * from FileChooserBuilder */ public void loadModel(boolean loadFromFile) { File[] files; // Selects files with faces (by dialog or from JSON file) if (!loadFromFile) { files = new FileChooserBuilder(ProjectTopComp.class) .setTitle("Open human face(s)") .setDefaultWorkingDirectory(new File(System.getProperty("user.home"))) //.setApproveText("Add") .setFileFilter(new FileNameExtensionFilter("obj files (*.obj)", "obj")) .setAcceptAllFileFilterUsed(true) .showMultiOpenDialog(); } else { files = new File[project.getCfg().getPaths().size()]; files = project.getCfg().openFiles().toArray(files); project.getCfg().clearPaths(); } if (files == null) { System.out.print("No file chosen."); } else { for (File file : files) { Path path = Paths.get(file.getAbsolutePath()); String name = path.toString().substring(path.toString() .lastIndexOf(File.separatorChar) + 1, path.toString().lastIndexOf('.')); if (project.addNewPath(path)) { model.addRowWithName(name, path); } else { JOptionPane.showMessageDialog(this, String.format("Model %s is already loaded", name)); } } } } /** * Loads tabs from project file */ private void loadTabs() { // Load Single face tabs project.getCfg().getSingleTabFaces().forEach(name -> { HumanFace face1 = project.loadFace(name); if (face1 != null) { createSingleFaceTab(face1, name, true); } }); // Load Face to face tabs project.getCfg().getFaceToFaceTabFaces().keySet().forEach(name -> { HumanFace face1 = project.loadFace(name); if (face1 != null) { project.getCfg().getFaceToFaceTabFaces().get(name).forEach(otherName -> { HumanFace face2 = project.loadFace(otherName); if (face2 != null) { createFaceToFaceTab(face1, face2, name + ":" + otherName, true); } }); } }); } /** * Creates and opens tab with one face * @param face which will be analyzed * @param name name of the tab (name of the model) */ private void createSingleFaceTab(HumanFace face, String name, boolean loadFromFile) { ActionListener tabCloseListener = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { closeTab(e); } }; FaceTab newTab = new FaceTab(face, null, name, tabCloseListener); if (!tabs.contains(newTab)) { tabs.add(newTab); if (!loadFromFile) { project.addNewSingleFaceTabFace(name); } newTab.open(); newTab.requestActive(); this.project.setSaved(false); } else { tabs.stream().filter(t -> (t.equals(newTab))).forEachOrdered(t -> { t.requestActive(); }); } } /** * Creates and opens tab with two faces (1:1 analysis) * @param face1 which will be analyzed * @param face2 which will be analyzed * @param name name of the tab */ private void createFaceToFaceTab(HumanFace face1, HumanFace face2, String nameOfTab, boolean loadFromFile) { ActionListener tabCloseListener = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { closeTab(e); } }; FaceTab newTab = new FaceTab(face1, face2, nameOfTab, tabCloseListener); if (!tabs.contains(newTab)) { tabs.add(newTab); if (!loadFromFile) { project.addNewFaceToFaceTabFace(face1.getShortName(), face2.getShortName()); } newTab.open(); newTab.requestActive(); this.project.setSaved(false); } else { tabs.stream().filter(t -> (t.equals(newTab))).forEachOrdered(t -> { t.requestActive(); }); } } /** * Creates and opens tab with multiple faces for N:N analysis * @param faces faces to be analyzed * @param name name of the tab */ private void createManyToManyTab(String name, List<Path> faces) { ActionListener tabCloseListener = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { closeTab(e); } }; FaceTab newTab = new FaceTab(faces, name, tabCloseListener); if (!tabs.contains(newTab)) { tabs.add(newTab); } newTab.open(); newTab.requestActive(); } /** * Opens info panel with face state information * @param faceName String name of face * @param selected Boolean true if some face is selected from list, false otherwise */ public void checkFaceState(String faceName, boolean selected) { Path path = project.getCfg().getPathToFaceByName(faceName); faceStatePanel.newSelection(selected, faceName, path); this.repaint(); } /** * Asks user whether he wants to create new empty project, or open existing * project */ public void openExistingOrNewProject() { File recentProjectFile = getRecentProject(); if (recentProjectFile != null) { openProjectFromFile(recentProjectFile); return; } ImageIcon newProjectImage = new ImageIcon(ProjectTopComp.class.getClassLoader().getResource("/" + "new.png")); ImageIcon existingProjectImage = new ImageIcon(ProjectTopComp.class.getClassLoader().getResource("/" + "open.png")); Object[] options = {newProjectImage, existingProjectImage}; int choice = JOptionPane.showOptionDialog(this, "Would you like to create a new project or open an existing project?", "Select project", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (choice == 1) { openProject(); } } /** * Resets all project attributes */ private void resetProject() { while (!tabs.isEmpty()) { tabs.get(0).close(); } faceStatePanel.clearLoadedFaces(); filterPanel.clearFiltering(); model.setRowCount(0); checkFaceState(null, false); selectedRows.clear(); userPreferences.remove("pathToMostRecentProject"); } /** * Checks whether current project is saved, if not then asks user if he wants * to save it * @return false if user cancels selection, true otherwise */ private boolean loadNewProject() { if (!project.isSaved()) { int showConfirmDialog = JOptionPane.showConfirmDialog(this, "Project is not saved. Would you like to save project?", "Save project", JOptionPane.YES_NO_CANCEL_OPTION); switch (showConfirmDialog) { case JOptionPane.YES_OPTION: saveProject(); break; case JOptionPane.CANCEL_OPTION: case JOptionPane.CLOSED_OPTION: return false; default: break; } } return true; } /** * Saves current project */ public void saveProject() { File file; // If current project was saved before String path = userPreferences.get("pathToMostRecentProject", ""); if (path != null && !path.isEmpty()) { file = Paths.get(path).toFile(); // Project was not saved before, user chooses new path where to save project } else { JFileChooser chooser = new JFileChooser(); //chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setFileFilter(new FileNameExtensionFilter("json files (*.json)", "json")); chooser.setAcceptAllFileFilterUsed(true); chooser.showSaveDialog(null); file = chooser.getSelectedFile(); } if (file != null) { String filePath = file.getAbsolutePath(); if (!filePath.endsWith(".json")) { file = new File(filePath.concat(".json")); } try { mapper.writeValue(file, project.getCfg()); userPreferences.put("pathToMostRecentProject", file.getAbsolutePath()); project.setSaved(true); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } } /** * Opens project from file * @param f File */ private void openProjectFromFile(File f) { 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); JOptionPane.showMessageDialog(this, "Couldn't load project", "Loading project failed", JOptionPane.ERROR_MESSAGE); } } } /** * 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); } /** * Creates new project */ private void newProject() { resetProject(); project.setCfg(new ProjectConfiguration()); project.setSaved(true); } /** * Closes tab * @param e ActionEvent */ private void closeTab(ActionEvent e) { FaceTab tab = (FaceTab)e.getSource(); for (FaceTab t : tabs) { if (t.equals(tab)) { if (e.getActionCommand().equals("FaceTab")) { this.project.removeFaceTab(t.getNameOfFace1()); } else if (e.getActionCommand().equals("FaceToFaceTab")){ this.project.removeFaceToFaceTab(t.getNameOfFace1(), t.getNameOfFace2()); } tabs.remove(t); break; } } //this.requestActive(); } /** * Loads currently selected (clicked in table) face geometry info */ 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); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addButton; private javax.swing.JButton analyseButton; private javax.swing.JPanel buttonsPanel; private javax.swing.JButton deselectAllButton; private javax.swing.JButton inflateButton; private javax.swing.JButton newProjectButton; private javax.swing.JButton openProjectButton; private javax.swing.JButton removeButton; private javax.swing.JButton saveProjectButton; private javax.swing.JButton selectAllButton; private javax.swing.JTable table; private javax.swing.JScrollPane tableScrollPane; // End of variables declaration//GEN-END:variables }