package com.compomics.software.settings.gui; import com.compomics.util.Util; import com.compomics.software.settings.PathKey; import com.compomics.software.settings.UtilitiesPathPreferences; import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import javax.swing.ImageIcon; import javax.swing.JOptionPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import no.uib.jsparklines.extra.TrueFalseIconRenderer; /** * Dialog used to set paths. * * @author Marc Vaudel */ public class PathSettingsDialog extends javax.swing.JDialog { /** * Boolean indicating whether the process was canceled by the user. */ private boolean canceled = false; /** * Original map of the paths to set. */ private HashMap<PathKey, String> originalKeyToPathMap = null; /** * Map of the paths to set. */ private HashMap<PathKey, String> keyToPathMap = null; /** * List of paths. */ private ArrayList<PathKey> keyList = null; /** * Name to key map. */ private HashMap<String, PathKey> nameToKey = null; /** * The tool name. */ private String toolName; /** * Tooltips for the paths. */ private ArrayList<String> pathsToolTips; /** * The path table column header tooltips. */ private ArrayList<String> pathTableToolTips; /** * Creates a new PathSettingsDialog. * * @param parent the parent frame * @param toolName the tool name * @param keyToPathMap the initial path settings */ public PathSettingsDialog(java.awt.Frame parent, String toolName, HashMap<PathKey, String> keyToPathMap) { super(parent, true); this.toolName = toolName; this.originalKeyToPathMap = keyToPathMap; this.keyToPathMap = (HashMap<PathKey, String>) keyToPathMap.clone(); nameToKey = new HashMap<String, PathKey>(keyToPathMap.size()); for (PathKey key : keyToPathMap.keySet()) { nameToKey.put(key.getId(), key); } ArrayList<String> names = new ArrayList<String>(nameToKey.keySet()); Collections.sort(names); keyList = new ArrayList<PathKey>(names.size()); pathsToolTips = new ArrayList<String>(names.size()); for (String name : names) { PathKey pathKey = nameToKey.get(name); keyList.add(pathKey); pathsToolTips.add(pathKey.getDescription()); } initComponents(); setUpGUI(parent, toolName); setLocationRelativeTo(parent); setTitle("Resource Folders"); setVisible(true); } /** * Sets up the GUI components. * * @param toolName the tool name * @param parent the parent frame */ public void setUpGUI(java.awt.Frame parent, String toolName) { informationTxt.setText(toolName + " uses the following directories to store setting files.\n\nA warning sign indicates folders where " + toolName + " cannot write. Failing to save setting files can impair the tool functionality."); pathTable.getTableHeader().setReorderingAllowed(false); pathTable.getColumn(" ").setMaxWidth(30); pathTable.getColumn(" ").setMinWidth(30); pathTable.getColumn(" ").setMaxWidth(30); pathTable.getColumn(" ").setMinWidth(30); pathTable.getColumn(" ").setCellRenderer(new TrueFalseIconRenderer( new ImageIcon(parent.getClass().getResource("/icons/accept.png")), new ImageIcon(parent.getClass().getResource("/icons/warning.png")), "OK", "Warning")); // make sure that the scroll panes are see-through pathTableScrollPane.getViewport().setOpaque(false); pathTableToolTips = new ArrayList<String>(); pathTableToolTips.add(null); pathTableToolTips.add("Path Name"); pathTableToolTips.add("Path"); pathTableToolTips.add("Path Check"); } /** * 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() { pathSettingsPopupMenu = new javax.swing.JPopupMenu(); editPathMenuItem = new javax.swing.JMenuItem(); setDefaultPath = new javax.swing.JMenuItem(); pathSettingsJPanel = new javax.swing.JPanel(); cancelButton = new javax.swing.JButton(); okButton = new javax.swing.JButton(); tablePanel = new javax.swing.JPanel(); pathTableScrollPane = new javax.swing.JScrollPane(); pathTable = new JTable() { protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel) { public String getToolTipText(MouseEvent e) { java.awt.Point p = e.getPoint(); int index = columnModel.getColumnIndexAtX(p.x); int realIndex = columnModel.getColumn(index).getModelIndex(); String tip = (String) pathTableToolTips.get(realIndex); return tip; } }; } }; helpLabel = new javax.swing.JLabel(); informationPanel = new javax.swing.JPanel(); informationScrollPane = new javax.swing.JScrollPane(); informationTxt = new javax.swing.JTextArea(); editPathMenuItem.setText("Edit Path"); editPathMenuItem.setToolTipText("Edit Selected Path"); editPathMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editPathMenuItemActionPerformed(evt); } }); pathSettingsPopupMenu.add(editPathMenuItem); setDefaultPath.setText("Set Default Path"); setDefaultPath.setToolTipText("Set a path for all files"); setDefaultPath.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { setDefaultPathActionPerformed(evt); } }); pathSettingsPopupMenu.add(setDefaultPath); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); pathSettingsJPanel.setBackground(new java.awt.Color(230, 230, 230)); cancelButton.setText("Cancel"); cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancelButtonActionPerformed(evt); } }); okButton.setText("OK"); okButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { okButtonActionPerformed(evt); } }); tablePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Path Settings")); tablePanel.setOpaque(false); pathTableScrollPane.setOpaque(false); pathTable.setModel(new PathsTableModel()); pathTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent evt) { pathTableMouseReleased(evt); } }); pathTableScrollPane.setViewportView(pathTable); javax.swing.GroupLayout tablePanelLayout = new javax.swing.GroupLayout(tablePanel); tablePanel.setLayout(tablePanelLayout); tablePanelLayout.setHorizontalGroup( tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(tablePanelLayout.createSequentialGroup() .addContainerGap() .addComponent(pathTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 808, Short.MAX_VALUE) .addContainerGap()) ); tablePanelLayout.setVerticalGroup( tablePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(tablePanelLayout.createSequentialGroup() .addContainerGap() .addComponent(pathTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE) .addContainerGap()) ); helpLabel.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N helpLabel.setText("Right-click to edit the paths"); informationPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Information")); informationPanel.setOpaque(false); informationTxt.setEditable(false); informationTxt.setColumns(20); informationTxt.setLineWrap(true); informationTxt.setRows(5); informationTxt.setWrapStyleWord(true); informationTxt.setOpaque(false); informationScrollPane.setViewportView(informationTxt); javax.swing.GroupLayout informationPanelLayout = new javax.swing.GroupLayout(informationPanel); informationPanel.setLayout(informationPanelLayout); informationPanelLayout.setHorizontalGroup( informationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(informationPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(informationScrollPane) .addContainerGap()) ); informationPanelLayout.setVerticalGroup( informationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(informationPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(informationScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); javax.swing.GroupLayout pathSettingsJPanelLayout = new javax.swing.GroupLayout(pathSettingsJPanel); pathSettingsJPanel.setLayout(pathSettingsJPanelLayout); pathSettingsJPanelLayout.setHorizontalGroup( pathSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pathSettingsJPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(pathSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pathSettingsJPanelLayout.createSequentialGroup() .addGap(10, 10, 10) .addComponent(helpLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cancelButton)) .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(informationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); pathSettingsJPanelLayout.setVerticalGroup( pathSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pathSettingsJPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(informationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pathSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(cancelButton) .addComponent(okButton) .addComponent(helpLabel)) .addContainerGap()) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(pathSettingsJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(pathSettingsJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pack(); }// </editor-fold>//GEN-END:initComponents /** * Edit the selected path. * * @param evt */ private void editPathMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editPathMenuItemActionPerformed editSelectedPath(); }//GEN-LAST:event_editPathMenuItemActionPerformed /** * Set the default path. * * @param evt */ private void setDefaultPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setDefaultPathActionPerformed setDefaultPath(); }//GEN-LAST:event_setDefaultPathActionPerformed /** * Edit the selected path. * * @param evt */ private void pathTableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pathTableMouseReleased if (evt != null && pathTable.rowAtPoint(evt.getPoint()) != -1) { pathTable.setRowSelectionInterval(pathTable.rowAtPoint(evt.getPoint()), pathTable.rowAtPoint(evt.getPoint())); } if (evt != null && evt.getButton() == MouseEvent.BUTTON3 && pathTable.getSelectedRow() != -1) { pathSettingsPopupMenu.show(pathTable, evt.getX(), evt.getY()); } if (evt != null && evt.getButton() == MouseEvent.BUTTON1 && evt.getClickCount() == 2) { editSelectedPath(); } }//GEN-LAST:event_pathTableMouseReleased /** * Save the paths and restart the tool if a change was detected. * * @param evt */ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed boolean changed = false; for (PathKey pathKey : originalKeyToPathMap.keySet()) { String newPath = keyToPathMap.get(pathKey); String originalPath = originalKeyToPathMap.get(pathKey); if ((newPath != null && originalPath == null) || (newPath == null && originalPath != null) || (newPath != null && originalPath != null && !originalPath.equals(newPath))) { changed = true; break; } } if (changed) { int outcome = JOptionPane.showConfirmDialog(this, toolName + " needs to restart in order to take the new settings into account. Restart now?", "Restart Requested", JOptionPane.YES_NO_CANCEL_OPTION); if (outcome == JOptionPane.YES_OPTION) { dispose(); } else if (outcome == JOptionPane.NO_OPTION) { canceled = true; dispose(); } else { // cancel // do nothing } } else { canceled = true; dispose(); } }//GEN-LAST:event_okButtonActionPerformed /** * Close the dialog without saving the changes. * * @param evt */ private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed canceled = true; dispose(); }//GEN-LAST:event_cancelButtonActionPerformed /** * Close the dialog without saving the changes. * * @param evt */ private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing canceled = true; }//GEN-LAST:event_formWindowClosing // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton cancelButton; private javax.swing.JMenuItem editPathMenuItem; private javax.swing.JLabel helpLabel; private javax.swing.JPanel informationPanel; private javax.swing.JScrollPane informationScrollPane; private javax.swing.JTextArea informationTxt; private javax.swing.JButton okButton; private javax.swing.JPanel pathSettingsJPanel; private javax.swing.JPopupMenu pathSettingsPopupMenu; private javax.swing.JTable pathTable; private javax.swing.JScrollPane pathTableScrollPane; private javax.swing.JMenuItem setDefaultPath; private javax.swing.JPanel tablePanel; // End of variables declaration//GEN-END:variables /** * Edits the selected path. */ private void editSelectedPath() { int selectedRow = pathTable.getSelectedRow(); String name = (String) pathTable.getValueAt(selectedRow, 1); PathKey pathKey = nameToKey.get(name); File selectedFile = Util.getUserSelectedFolder(this, "Select " + pathKey.getId() + " Folder", keyToPathMap.get(pathKey), pathKey.getId() + " Folder", "Select", false); if (selectedFile != null) { keyToPathMap.put(pathKey, selectedFile.getAbsolutePath()); ((DefaultTableModel) pathTable.getModel()).fireTableDataChanged(); } } /** * Sets a default path. */ private void setDefaultPath() { File selectedFile = Util.getUserSelectedFolder(this, "Select Default Folder", null, "Default Folder", "Select", false); if (selectedFile != null) { for (PathKey pathKey : keyToPathMap.keySet()) { keyToPathMap.put(pathKey, selectedFile.getAbsolutePath()); } ((DefaultTableModel) pathTable.getModel()).fireTableDataChanged(); } } /** * Indicates whether the action was canceled by the user. (Or if no changes * where made to the settings.) * * @return true if the action was canceled by the user */ public boolean isCanceled() { return canceled; } /** * Returns the path settings in a map: key | path. * * @return the path settings in a map */ public HashMap<PathKey, String> getKeyToPathMap() { return keyToPathMap; } /** * Table model for the Paths table. */ private class PathsTableModel extends DefaultTableModel { /** * Creates a new table model. */ public PathsTableModel() { } @Override public int getRowCount() { if (keyToPathMap == null) { return 0; } return keyToPathMap.size(); } @Override public int getColumnCount() { return 4; } @Override public String getColumnName(int column) { switch (column) { case 0: return " "; case 1: return "Name"; case 2: return "Path"; case 3: return " "; default: return ""; } } @Override public Object getValueAt(int row, int column) { PathKey pathKey = keyList.get(row); switch (column) { case 0: return row + 1; case 1: return pathKey.getId(); case 2: String path = keyToPathMap.get(pathKey); if (path != null) { File file = new File(path); return file.getAbsolutePath(); } else { return "Default"; } case 3: String folderPath = keyToPathMap.get(pathKey); if (folderPath != null) { return UtilitiesPathPreferences.testPath(folderPath); } return true; default: return ""; } } @Override public Class getColumnClass(int columnIndex) { for (int i = 0; i < getRowCount(); i++) { if (getValueAt(i, columnIndex) != null) { return getValueAt(i, columnIndex).getClass(); } } return String.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } } }