Java tutorial
/** * Title: Force Field X. * * Description: Force Field X - Software for Molecular Biophysics. * * Copyright: Copyright (c) Michael J. Schnieders 2001-2017. * * This file is part of Force Field X. * * Force Field X is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * Force Field X is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * Linking this library statically or dynamically with other modules is making a * combined work based on this library. Thus, the terms and conditions of the * GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, and * to copy and distribute the resulting executable under terms of your choice, * provided that you also meet, for each linked independent module, the terms * and conditions of the license of that module. An independent module is a * module which is not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the library, but * you are not obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package ffx.ui; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.Preferences; import static java.lang.String.format; import static java.util.Arrays.copyOfRange; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.border.Border; import javax.swing.border.EtchedBorder; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.FilenameUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import ffx.potential.Utilities.FileType; import ffx.potential.bonded.Residue; import ffx.potential.parsers.SystemFilter; import ffx.ui.commands.DTDResolver; import ffx.utilities.Keyword; import ffx.utilities.StringUtils; /** * The ModelingPanel class encapsulates functionality needed to run FFX Modeling * Commands. * * @author Michael J. Schnieders * */ public class ModelingPanel extends JPanel implements ActionListener, MouseListener { private static final Logger logger = Logger.getLogger(ModelingPanel.class.getName()); private static final Preferences prefs = Preferences.userNodeForPackage(ModelingPanel.class); private static final long serialVersionUID = 1L; private final MainPanel mainPanel; /** * Active System */ private FFXSystem activeSystem = null; /** * File Type for the Active System */ private FileType activeFileType = null; /** * Currently Selected Command */ private String activeCommand = null; /** * File Types for this Command */ private final ArrayList<FileType> commandFileTypes = new ArrayList<>(); /** * Actions to take for this Command when it finishes */ private String commandActions = "NONE"; /** * Executing Commands */ private final ArrayList<Thread> executingCommands = new ArrayList<>(); /** * Log Settings */ private final JComboBox<String> logSettings = new JComboBox<>(); private String logString = null; /** * Commands for supported file types */ private NodeList commandList; private JComboBox<String> xyzCommands; private JComboBox<String> intCommands; private JComboBox<String> arcCommands; private JComboBox<String> pdbCommands; private JComboBox<String> anyCommands; private JComboBox<String> currentCommandBox; /** * The CommandPanel holds the toolBar (north), splitPane (center) and * statusLabel (south). */ private JPanel commandPanel; private JToolBar toolBar; /** * The splitPane holds the optionsTabbedPane (top) and descriptScrollPane * (bottom). */ private JSplitPane splitPane; private JLabel statusLabel; private JTabbedPane optionsTabbedPane; private JScrollPane descriptScrollPane; private JTextArea descriptTextArea; private JCheckBoxMenuItem descriptCheckBox; private final ArrayList<JLabel> conditionals = new ArrayList<>(); /** * Command input is formed in the commandTextArea, then exported to an input * file. */ private JTextArea commandTextArea; /** * Nucleic Acid and Protein builder components. */ private final JComboBox<String> acidComboBox = new JComboBox<>(); private final JTextField acidTextField = new JTextField(); private final JTextArea acidTextArea = new JTextArea(); private JComboBox<String> conformationComboBox; private JScrollPane acidScrollPane = null; private JPanel aminoPanel = null; private JPanel nucleicPanel = null; /** * Reused FlowLayout. */ private final FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT, 5, 5); /** * Reused BorderLayout. */ private final BorderLayout borderLayout = new BorderLayout(); /** * Reused EtchedBorder. */ private final Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED); private final JTextField sizer = new JTextField(20); private JButton jbLaunch; private JButton jbStop; private FFXLauncher ffxLauncher = null; private Thread ffxThread = null; /** * Constructor * * @param mainPanel a {@link ffx.ui.MainPanel} object. */ public ModelingPanel(MainPanel mainPanel) { super(); this.mainPanel = mainPanel; initialize(); } /** * {@inheritDoc} */ @Override public void actionPerformed(ActionEvent evt) { synchronized (this) { String actionCommand = evt.getActionCommand(); // A change to the selected TINKER Command switch (actionCommand) { case "FFXCommand": JComboBox jcb = (JComboBox) toolBar.getComponentAtIndex(2); String com = jcb.getSelectedItem().toString(); if (!com.equals(activeCommand)) { activeCommand = com.toLowerCase(); loadCommand(); } break; case "LogSettings": // A change to the Log Settings. loadLogSettings(); statusLabel.setText(" " + createCommandInput()); break; case "Launch": // Launch the selected Force Field X command. runScript(); break; case "NUCLEIC": case "PROTEIN": // Editor functions for the Protein and Nucleic Acid Builders builderCommandEvent(evt); break; case "Conditional": // Some command options are conditional on other input. conditionalCommandEvent(evt); break; case "End": // End the currently executing command. setEnd(); break; case "Delete": // Delete log files. deleteLogs(); break; case "Description": // Allow command descriptions to be hidden. JCheckBoxMenuItem box = (JCheckBoxMenuItem) evt.getSource(); setDivider(box.isSelected()); break; default: logger.log(Level.WARNING, "ModelingPanel ActionCommand not recognized: {0}", evt); break; } } } /* * This handles Protein and Nucleic Acid builder events. */ private void builderCommandEvent(ActionEvent evt) { JButton button = (JButton) evt.getSource(); String arg = evt.getActionCommand(); int index = acidComboBox.getSelectedIndex(); String selected = (String) acidComboBox.getItemAt(index); if ("Remove".equals(button.getText())) { // Remove one entry if (acidComboBox.getItemCount() > 0) { acidComboBox.removeItemAt(index); index--; } } else if ("Edit".equals(button.getText())) { String entry = new String(acidTextField.getText()); // Allow editing - should add more input validation here if (!entry.equals("")) { String s[] = entry.trim().split(" +"); String newResidue = s[0].toUpperCase(); if ("NUCLEIC".equals(arg)) { // Residue.NA3Set.contains(newResidue); try { Residue.NA3.valueOf(newResidue); acidComboBox.removeItemAt(index); acidComboBox.insertItemAt("" + index + " " + entry, index); } catch (Exception e) { } } else { try { Residue.AA3.valueOf(newResidue); acidComboBox.removeItemAt(index); acidComboBox.insertItemAt("" + index + " " + entry, index); } catch (Exception e) { } } } } else if ("Reset".equals(button.getText())) { // Remove all entries acidComboBox.removeAllItems(); acidTextArea.setText(""); } else { // A base/residue button was selected String newResidue = button.getText(); if ("PROTEIN".equals(arg)) { String c = (String) conformationComboBox.getSelectedItem(); if (!c.toUpperCase().startsWith("DEFAULT")) { c = c.substring(c.indexOf("[") + 1, c.indexOf("]")); newResidue = newResidue + " " + c; } acidComboBox.insertItemAt("" + index + " " + newResidue, index + 1); index++; } else { if (!newResidue.equalsIgnoreCase("MOL")) { acidComboBox.insertItemAt("" + index + " " + newResidue, index + 1); index++; } else if (!selected.equalsIgnoreCase("MOL")) { acidComboBox.insertItemAt("" + index + " " + newResidue, index + 1); index++; } } } // Create the condensed sequence view. StringBuilder sequence = new StringBuilder(); for (int i = 0; i < acidComboBox.getItemCount(); i++) { String s[] = ((String) acidComboBox.getItemAt(i)).trim().toUpperCase().split(" +"); if (s.length > 1) { if (s[1].equalsIgnoreCase("MOL")) { sequence.append(s[1]).append("\n"); } else { sequence.append(s[1]).append(" "); } } } // Renumber the sequence. acidTextArea.setText(sequence.toString()); for (int i = 0; i < acidComboBox.getItemCount(); i++) { String s = (String) acidComboBox.getItemAt(i); s = s.substring(s.indexOf(" "), s.length()).trim(); acidComboBox.removeItemAt(i); acidComboBox.insertItemAt("" + (i + 1) + " " + s, i); } // Set the selected entry and fill in the edit textField. if (index < 0) { index = 0; } if (index > acidComboBox.getItemCount() - 1) { index = acidComboBox.getItemCount() - 1; } acidComboBox.setSelectedIndex(index); String s = (String) acidComboBox.getItemAt(index); if (s != null) { acidTextField.setText(s.substring(s.indexOf(" "), s.length()).trim()); } else { acidTextField.setText(""); } } /** * This handles conditional command option input. * * @param evt ActionEvent */ private void conditionalCommandEvent(ActionEvent evt) { Object source = evt.getSource(); if (source instanceof JRadioButton) { JRadioButton jrb = (JRadioButton) source; String selection = jrb.getText().toLowerCase(); for (JLabel label : conditionals) { JTextField jtf = (JTextField) label.getLabelFor(); String cupon = label.getName().toLowerCase(); if (cupon.contains(selection) && jrb.isSelected()) { label.setEnabled(true); jtf.setEnabled(true); } else { label.setEnabled(false); jtf.setEnabled(false); } } } else if (source instanceof JCheckBox) { JCheckBox jcb = (JCheckBox) source; String selection = jcb.getText().toLowerCase(); for (JLabel label : conditionals) { String cupon = label.getName().toLowerCase(); JTextField jtf = (JTextField) label.getLabelFor(); if (cupon.contains(selection) && jcb.isSelected()) { label.setEnabled(true); jtf.setEnabled(true); } else { label.setEnabled(false); jtf.setEnabled(false); } } } statusLabel.setText(" " + createCommandInput()); } /** * Create a string representing the modeling command to execute. * * @return the modeling command string. */ private String createCommandInput() { StringBuilder commandLineParams = new StringBuilder(activeCommand + " "); // Now append command line input to a TextArea, one option per line. // This TextArea gets dumped to an input file. commandTextArea.setText(""); int numparams = optionsTabbedPane.getTabCount(); for (int i = 0; i < numparams; i++) { // A few cases require that a newLine not be generated between // options. boolean newLine = true; // The optionString will collect the parameters for this Option, // then append them to the CommandTextArea. StringBuilder optionString = new StringBuilder(); JPanel optionPanel = (JPanel) optionsTabbedPane.getComponentAt(i); int numOptions = optionPanel.getComponentCount(); String title = optionsTabbedPane.getTitleAt(i); if (title.equalsIgnoreCase("Sequence")) { for (int k = 0; k < acidComboBox.getItemCount(); k++) { if (k != 0) { optionString.append("\n"); } String s = (String) acidComboBox.getItemAt(k); s = s.substring(s.indexOf(" "), s.length()).trim(); optionString.append(s); } // Need an extra newline for Nucleic if (activeCommand.equalsIgnoreCase("NUCLEIC")) { optionString.append("\n"); } } else { JPanel valuePanel = (JPanel) optionPanel.getComponent(numOptions - 1); int numValues = valuePanel.getComponentCount(); for (int j = 0; j < numValues; j++) { Component value = valuePanel.getComponent(j); if (value instanceof JCheckBox) { JCheckBox jcbox = (JCheckBox) value; if (jcbox.isSelected()) { optionString.append("-"); optionString.append(jcbox.getName()); optionString.append(" "); optionString.append(jcbox.getText()); } } else if (value instanceof JTextField) { JTextField jtfield = (JTextField) value; optionString.append("-"); optionString.append(jtfield.getName()); optionString.append(" "); optionString.append(jtfield.getText()); } else if (value instanceof JComboBox) { JComboBox jcb = (JComboBox) value; Object object = jcb.getSelectedItem(); if (object instanceof FFXSystem) { FFXSystem system = (FFXSystem) object; File file = system.getFile(); if (file != null) { String absolutePath = file.getAbsolutePath(); if (absolutePath.endsWith("xyz")) { absolutePath = absolutePath + "_1"; } optionString.append(absolutePath); } } } else if (value instanceof JRadioButton) { JRadioButton jrbutton = (JRadioButton) value; if (jrbutton.isSelected()) { if (!jrbutton.getText().equalsIgnoreCase("NONE")) { optionString.append("-"); optionString.append(jrbutton.getName()); optionString.append(" "); optionString.append(jrbutton.getText()); } if (title.equalsIgnoreCase("C-CAP")) { optionString.append("\n"); } } } } // Handle Conditional Options if (optionPanel.getComponentCount() == 3) { valuePanel = (JPanel) optionPanel.getComponent(1); // JLabel conditionalLabel = (JLabel) // valuePanel.getComponent(0); JTextField jtf = (JTextField) valuePanel.getComponent(1); if (jtf.isEnabled()) { String conditionalInput = jtf.getText(); // Post-Process the Input into Atom Pairs String postProcess = jtf.getName(); if (postProcess != null && postProcess.equalsIgnoreCase("ATOMPAIRS")) { String tokens[] = conditionalInput.split(" +"); StringBuilder atomPairs = new StringBuilder(); int atomNumber = 0; for (String token : tokens) { atomPairs.append(token); if (atomNumber++ % 2 == 0) { atomPairs.append(" "); } else { atomPairs.append("\n"); } } conditionalInput = atomPairs.toString(); } // Append a newline to "enter" the option string. // Append "conditional" input. optionString.append("\n").append(conditionalInput); } } } if (optionString.length() > 0) { commandTextArea.append(optionString.toString()); if (newLine) { commandTextArea.append("\n"); } } } String commandInput = commandTextArea.getText(); if (commandInput != null && !commandInput.trim().equalsIgnoreCase("")) { commandLineParams.append(commandInput); } // The final token on the command line is the structure file name, except // for protein and nucleic. if (!activeCommand.equalsIgnoreCase("Protein") && !activeCommand.equalsIgnoreCase("Nucleic")) { File file = activeSystem.getFile(); if (file != null) { String name = file.getName(); commandLineParams.append(name); commandLineParams.append(" "); } else { return null; } } return commandLineParams.toString(); } /** * Launch the TINKER command specified by the ModelingPanel * * @return a {@link ffx.ui.FFXExec} object. */ public FFXExec executeCommand() { FFXSystem s = mainPanel.getHierarchy().getActive(); String dir = MainPanel.getPWD().getAbsolutePath(); if (s != null) { File f = s.getFile(); if (f != null) { dir = f.getParent(); } } return launch(statusLabel.getText(), dir); } private JPanel getAminoAcidPanel() { if (aminoPanel != null) { return aminoPanel; } JPanel buttonPanel = new JPanel(new GridLayout(4, 5, 2, 2)); Residue.AA3 a[] = Residue.AA3.values(); for (int i = 0; i < 20; i++) { JButton button = new JButton(a[i].name()); button.setActionCommand("PROTEIN"); button.addActionListener(this); buttonPanel.add(button); } buttonPanel.setMaximumSize(buttonPanel.getPreferredSize()); aminoPanel = new JPanel(); aminoPanel.setLayout(new BoxLayout(aminoPanel, BoxLayout.Y_AXIS)); aminoPanel.add(buttonPanel); conformationComboBox = new JComboBox<>(Residue.Ramachandran); conformationComboBox.setFont(Font.decode("Monospaced")); conformationComboBox.setMaximumSize(buttonPanel.getPreferredSize()); aminoPanel.add(conformationComboBox); return aminoPanel; } /** * <p> * getAvailableCommands</p> * * @return a {@link java.util.ArrayList} object. */ public ArrayList<String> getAvailableCommands() { ArrayList<String> availableCommands = new ArrayList<>(); for (int i = 0; i < currentCommandBox.getItemCount(); i++) { availableCommands.add((String) currentCommandBox.getItemAt(i)); } return availableCommands; } /** ********************************************************************** * * @return a {@link java.lang.String} object. */ // Modeling Command Configuration public String getCommand() { return activeCommand; } private String getLogString(File currentLog) { String currentMode = (String) logSettings.getSelectedItem(); if (currentMode.startsWith("Create")) { currentLog = SystemFilter.version(currentLog); return " > \"" + currentLog.getAbsolutePath() + "\""; } else if (currentMode.startsWith("Append")) { return " >> \"" + currentLog.getAbsolutePath() + "\""; } else { return " > \"" + currentLog.getAbsolutePath() + "\""; } } /** * Get an ArrayList of executing jobs * * @return an ArrayList containing Thread objects */ public ArrayList<Thread> getModelingJobs() { return executingCommands; } private JPanel getNucleicAcidPanel() { if (nucleicPanel != null) { return nucleicPanel; } nucleicPanel = new JPanel(new GridLayout(3, 4, 2, 2)); Residue.NA3 a[] = Residue.NA3.values(); for (int i = 0; i < 8; i++) { JButton button = new JButton(a[i].name()); button.setActionCommand("NUCLEIC"); button.addActionListener(this); nucleicPanel.add(button); } JButton button = new JButton("MOL"); button.setActionCommand("NUCLEIC"); button.addActionListener(this); nucleicPanel.add(button); nucleicPanel.add(Box.createHorizontalBox()); nucleicPanel.add(Box.createHorizontalBox()); nucleicPanel.add(Box.createHorizontalBox()); nucleicPanel.setMaximumSize(nucleicPanel.getPreferredSize()); return nucleicPanel; } private void initCommandComboBox(JComboBox commands) { commands.setActionCommand("FFXCommand"); commands.setMaximumSize(xyzCommands.getPreferredSize()); commands.setEditable(false); commands.setToolTipText("Select a Modeling Command"); commands.setSelectedIndex(0); commands.addActionListener(this); } private void initialize() { // Command Description descriptTextArea = new JTextArea(); descriptTextArea.setEditable(false); descriptTextArea.setLineWrap(true); descriptTextArea.setWrapStyleWord(true); descriptTextArea.setDoubleBuffered(true); Insets insets = descriptTextArea.getInsets(); insets.set(5, 5, 5, 5); descriptTextArea.setMargin(insets); descriptScrollPane = new JScrollPane(descriptTextArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); descriptScrollPane.setBorder(etchedBorder); // Command Input commandTextArea = new JTextArea(); commandTextArea.setEditable(false); commandTextArea.setLineWrap(true); commandTextArea.setWrapStyleWord(true); commandTextArea.setDoubleBuffered(true); commandTextArea.setMargin(insets); // Command Options optionsTabbedPane = new JTabbedPane(); statusLabel = new JLabel(); statusLabel.setBorder(etchedBorder); statusLabel.setToolTipText(" Modeling command that will be executed"); commandPanel = new JPanel(flowLayout); commandPanel.add(optionsTabbedPane); splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, commandPanel, descriptScrollPane); splitPane.setContinuousLayout(true); splitPane.setResizeWeight(1.0d); splitPane.setOneTouchExpandable(true); setLayout(new BorderLayout()); add(splitPane, BorderLayout.CENTER); add(statusLabel, BorderLayout.SOUTH); // Initialize the Amino/Nucleic Acid ComboBox. acidComboBox.setEditable(false); acidComboBox.setMaximumSize(sizer.getPreferredSize()); acidComboBox.setPreferredSize(sizer.getPreferredSize()); acidComboBox.setMinimumSize(sizer.getPreferredSize()); acidComboBox.setFont(Font.decode("Monospaced")); acidTextField.setMaximumSize(sizer.getPreferredSize()); acidTextField.setMinimumSize(sizer.getPreferredSize()); acidTextField.setPreferredSize(sizer.getPreferredSize()); acidTextArea.setEditable(false); acidTextArea.setWrapStyleWord(true); acidTextArea.setLineWrap(true); acidTextArea.setFont(Font.decode("Monospaced")); acidScrollPane = new JScrollPane(acidTextArea); Dimension d = new Dimension(300, 400); acidScrollPane.setPreferredSize(d); acidScrollPane.setMaximumSize(d); acidScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); // Load the FFX commands.xml file that defines FFX commands. try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); db.setEntityResolver(new DTDResolver()); URL comURL = getClass().getClassLoader().getResource("ffx/ui/commands/commands.xml"); Document doc = db.parse(comURL.openStream()); NodeList nodelist = doc.getChildNodes(); Node commandroot = null; for (int i = 0; i < nodelist.getLength(); i++) { commandroot = nodelist.item(i); if (commandroot.getNodeName().equals("FFXCommands") && commandroot instanceof Element) { break; } } if (commandroot == null || !(commandroot instanceof Element)) { commandList = null; } commandList = ((Element) commandroot).getElementsByTagName("Command"); } catch (ParserConfigurationException | SAXException | IOException e) { System.err.println(e); } finally { if (commandList == null) { System.out.println("Force Field X commands.xml could not be parsed."); logger.severe("Force Field X will exit."); System.exit(-1); } } // Create a ComboBox with commands specific to each type of coordinate // file. xyzCommands = new JComboBox<>(); intCommands = new JComboBox<>(); arcCommands = new JComboBox<>(); pdbCommands = new JComboBox<>(); anyCommands = new JComboBox<>(); Element command; String name; int numcommands = commandList.getLength(); for (int i = 0; i < numcommands; i++) { command = (Element) commandList.item(i); name = command.getAttribute("name"); String temp = command.getAttribute("fileType"); if (temp.contains("ANY")) { temp = "XYZ INT ARC PDB"; anyCommands.addItem(name); } String[] types = temp.split(" +"); for (String type : types) { if (type.contains("XYZ")) { xyzCommands.addItem(name); } if (type.contains("INT")) { intCommands.addItem(name); } if (type.contains("ARC")) { arcCommands.addItem(name); } if (type.contains("PDB")) { pdbCommands.addItem(name); } } } initCommandComboBox(xyzCommands); initCommandComboBox(intCommands); initCommandComboBox(arcCommands); initCommandComboBox(pdbCommands); initCommandComboBox(anyCommands); currentCommandBox = anyCommands; activeCommand = (String) anyCommands.getSelectedItem(); // Load the default Command. loadCommand(); // Load the default Log File Settings. logSettings.setActionCommand("LogSettings"); loadLogSettings(); // Create the Toolbar. toolBar = new JToolBar("Modeling Commands", JToolBar.HORIZONTAL); toolBar.setLayout(new FlowLayout(FlowLayout.LEFT)); jbLaunch = new JButton(new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/cog_go.png"))); jbLaunch.setActionCommand("Launch"); jbLaunch.setToolTipText("Launch the Force Field X Command"); jbLaunch.addActionListener(this); insets.set(2, 2, 2, 2); jbLaunch.setMargin(insets); toolBar.add(jbLaunch); jbStop = new JButton(new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/stop.png"))); jbStop.setActionCommand("End"); jbStop.setToolTipText("Terminate the Current Force Field X Command"); jbStop.addActionListener(this); jbStop.setMargin(insets); jbStop.setEnabled(false); toolBar.add(jbStop); toolBar.addSeparator(); toolBar.add(anyCommands); currentCommandBox = anyCommands; toolBar.addSeparator(); /* toolBar.add(logSettings); JButton jbdelete = new JButton(new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/page_delete.png"))); jbdelete.setActionCommand("Delete"); jbdelete.setToolTipText("Delete Log Files"); jbdelete.addActionListener(this); jbdelete.setMargin(insets); toolBar.add(jbdelete); toolBar.addSeparator(); */ ImageIcon icinfo = new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/information.png")); descriptCheckBox = new JCheckBoxMenuItem(icinfo); descriptCheckBox.addActionListener(this); descriptCheckBox.setActionCommand("Description"); descriptCheckBox.setToolTipText("Show/Hide Modeling Command Descriptions"); descriptCheckBox.setMargin(insets); toolBar.add(descriptCheckBox); toolBar.add(new JLabel("")); toolBar.setBorderPainted(false); toolBar.setFloatable(false); toolBar.setRollover(true); add(toolBar, BorderLayout.NORTH); // Load ModelingPanel preferences. Preferences prefs = Preferences.userNodeForPackage(ffx.ui.ModelingPanel.class); descriptCheckBox.setSelected(!prefs.getBoolean("JobPanel_description", true)); descriptCheckBox.doClick(); } private void runScript() { String name = activeCommand; name = name.replace('.', File.separatorChar); ClassLoader loader = getClass().getClassLoader(); URL embeddedScript = loader.getResource("ffx/scripts/" + name + ".ffx"); if (embeddedScript == null) { embeddedScript = loader.getResource("ffx/scripts/" + name + ".groovy"); } File scriptFile = null; if (embeddedScript != null) { try { scriptFile = new File( StringUtils.copyInputStreamToTmpFile(embeddedScript.openStream(), name, ".ffx")); } catch (IOException e) { logger.log(Level.WARNING, "Exception extracting embedded script {0}\n{1}", new Object[] { embeddedScript.toString(), e.toString() }); } } if (scriptFile != null && scriptFile.exists()) { String argLine = statusLabel.getText().replace('\n', ' '); String args[] = argLine.trim().split(" +"); // Remove the command (first token) and system name (last token). args = copyOfRange(args, 1, args.length - 1); List<String> argList = Arrays.asList(args); ffxLauncher = new FFXLauncher(argList, scriptFile); ffxThread = new Thread(ffxLauncher); ffxThread.setName(statusLabel.getText()); ffxThread.setPriority(Thread.MAX_PRIORITY); ffxThread.start(); } else { logger.warning(format("%s was not found.", name)); } } public void enableLaunch(boolean enable) { jbLaunch.setEnabled(enable); jbStop.setEnabled(!enable); } private class FFXLauncher implements Runnable { List<String> argList; File scriptFile; public FFXLauncher(List<String> argList, File scriptFile) { this.argList = argList; this.scriptFile = scriptFile; } @Override public void run() { mainPanel.getModelingShell().setArgList(argList); mainPanel.open(scriptFile, null); } } /** * Launch the active command on the active system in the specified * directory. * * @param command The command to be excuted. * @param dir The directory to execute the command in. * @return a {@link ffx.ui.FFXExec} object. */ public FFXExec launch(String command, String dir) { logger.log(Level.INFO, "Command: {0}\nDirectory: {1}", new Object[] { command, dir }); synchronized (this) { // Check that the TINKER *.exe exists in TINKER/bin String path = MainPanel.ffxDir.getAbsolutePath(); File exe = new File(path + File.separator + activeCommand.toLowerCase()); if (!exe.exists()) { exe = new File(exe.getAbsolutePath() + ".exe"); if (!exe.exists()) { String message = "The " + activeCommand + " executable was not found in " + path + ". Please use the 'Set TINKER...' dialog to change the TINKER directory."; JOptionPane.showMessageDialog(null, message, "Could not launch " + activeCommand, JOptionPane.ERROR_MESSAGE); return null; } } // Check that the directory to execute the command in is valid File dirf = new File(dir); if (!dirf.exists()) { logger.log(Level.WARNING, "Directory doesn''t exist: {0}", dirf.getAbsolutePath()); return null; } // Check if we need a key file if (!commandFileTypes.contains(FileType.ANY)) { if (activeSystem == null) { return null; } activeFileType = FileType.XYZ; // Check that the TINKER command executes on this file type if (!commandFileTypes.contains(activeFileType)) { String message = activeCommand.toUpperCase() + " does not execute on " + activeFileType + " files."; JOptionPane.showMessageDialog(null, message, "Could not launch " + activeCommand, JOptionPane.ERROR_MESSAGE); return null; } // Check that a key file exists or prompt to create one. if (activeSystem.getKeyFile() == null) { mainPanel.createKeyFile(activeSystem); // Give up if the key file is null. if (activeSystem.getKeyFile() == null) { return null; } } } else { // Determine names to use for the output of Protein/Nucleic command = createCommandInput(); String structureName = commandTextArea.getText().trim(); if (!structureName.equalsIgnoreCase("")) { structureName = (structureName.split("\n"))[0]; if (structureName != null) { structureName = structureName.trim(); int dot = structureName.lastIndexOf("."); if (dot > 0) { structureName = structureName.substring(0, dot); } } } // If the above fails, just use the name of the executable // (protein or nulceic) if (structureName == null) { structureName = activeCommand.toLowerCase(); } File file = new File(dir + File.separator + structureName + ".xyz"); file = SystemFilter.version(file); activeSystem = new FFXSystem(file, null, Keyword.loadProperties(file)); File logFile = new File(file.getParent() + File.separator + structureName + ".log"); activeSystem.setLogFile(logFile); loadLogSettings(); activeFileType = FileType.ANY; // Need to have a parameter file chosen. mainPanel.openKey(activeSystem, true); if (activeSystem.getKeyFile() == null) { return null; } } // Decide on a Log file if (((String) logSettings.getSelectedItem()).startsWith("Create")) { File newLog = SystemFilter.version(activeSystem.getLogFile()); activeSystem.setLogFile(newLog); } String logName = activeSystem.getLogFile().getAbsolutePath(); // Determine the command string command = createCommandInput(); // If a new structure file will be created, determine what the name // will be. File newFile = null; if (commandActions.toUpperCase().contains("LOAD")) { File oldFile = activeSystem.getFile(); if (commandActions.toUpperCase().contains("LOADXYZ")) { String fileName = oldFile.getAbsolutePath(); int dot = fileName.lastIndexOf("."); if (dot > 0) { fileName = fileName.substring(0, dot) + ".xyz"; } oldFile = new File(fileName); } else if (commandActions.toUpperCase().contains("LOADINT")) { String fileName = oldFile.getAbsolutePath(); int dot = fileName.lastIndexOf("."); if (dot > 0) { fileName = fileName.substring(0, dot) + ".int"; } oldFile = new File(fileName); } else if (commandActions.toUpperCase().contains("LOADPDB")) { String fileName = oldFile.getAbsolutePath(); int dot = fileName.lastIndexOf("."); if (dot > 0) { fileName = fileName.substring(0, dot) + ".pdb"; } oldFile = new File(fileName); } newFile = SystemFilter.version(oldFile); } // Save any changes that have been made to the key file mainPanel.getKeywordPanel().saveChanges(); // Remove any TINKER *.END files removeEnd(); // Create the input file String commandInput = commandTextArea.getText(); if (commandInput != null && !commandInput.trim().equalsIgnoreCase("")) { File inputFile = new File(dir + File.separator + activeCommand.toLowerCase() + ".in"); inputFile.deleteOnExit(); try { FileWriter fw = new FileWriter(inputFile); fw.write(commandInput); fw.close(); } catch (Exception e) { logger.info(e.toString()); return null; } } // If the job progressively modifies coordinates, open a copy of it. boolean openOnto = false; if (commandActions.toUpperCase().contains("CONNECT")) { // If a version file is created, open it onto the structure used // to // display the job. if (newFile != null) { openOnto = true; } mainPanel.open(activeSystem.getFile(), activeCommand); try { while (mainPanel.isOpening()) { wait(10); } } catch (Exception e) { logger.info(e.toString()); return null; } activeSystem = mainPanel.getHierarchy().getActive(); } // Finally, create and execute the command in a new thread. FFXExec tinkerExec = new FFXExec(activeSystem, logName, command, dir, mainPanel, newFile, openOnto); Thread tinkerThread = new Thread(tinkerExec); tinkerThread.setPriority(Thread.NORM_PRIORITY); tinkerThread.setName(logName); // If the job progressively modifies coordinates, connect to it. if (commandActions.toUpperCase().contains("CONNECT")) { mainPanel.connectToTINKER(activeSystem, tinkerThread); } else { tinkerThread.start(); } // If some action should be taken when the job finishes, // add it to the Modeling Jobs Vector if (!commandActions.equalsIgnoreCase("NONE")) { executingCommands.add(tinkerThread); // mainPanel.getLogPanel().refreshStatus(); } return tinkerExec; } } /** * Load the active system into the JobPanel. This should be called whenever * the active system changes. * * @param active a {@link ffx.ui.FFXSystem} object. */ public void loadActive(FFXSystem active) { synchronized (this) { activeSystem = active; FileType fileType; // No Open Molecules if (activeSystem == null || activeSystem.isClosing()) { currentCommandBox = anyCommands; activeCommand = (String) anyCommands.getSelectedItem(); statusLabel.setText(" "); fileType = FileType.ANY; } else { fileType = FileType.XYZ; } if (fileType != activeFileType) { activeFileType = fileType; toolBar.remove(2); if (activeFileType == FileType.XYZ) { toolBar.add(xyzCommands); currentCommandBox = xyzCommands; } else if (activeFileType == FileType.INT) { toolBar.add(intCommands); currentCommandBox = intCommands; } else if (activeFileType == FileType.ARC) { toolBar.add(arcCommands); currentCommandBox = arcCommands; } else if (activeFileType == FileType.PDB) { toolBar.add(pdbCommands); currentCommandBox = pdbCommands; } else { toolBar.add(anyCommands); currentCommandBox = anyCommands; } toolBar.add(currentCommandBox, 2); toolBar.validate(); toolBar.repaint(); activeCommand = (String) currentCommandBox.getSelectedItem(); } loadCommand(); } } private void loadCommand() { synchronized (this) { // Force Field X Command Element command; // Command Options NodeList options; Element option; // Option Values NodeList values; Element value; // Options may be Conditional based on previous Option values (not // always supplied) NodeList conditionalList; Element conditional; // JobPanel GUI Components that change based on command JPanel optionPanel; // Clear the previous components commandPanel.removeAll(); optionsTabbedPane.removeAll(); conditionals.clear(); String currentCommand = (String) currentCommandBox.getSelectedItem(); if (currentCommand == null) { commandPanel.validate(); commandPanel.repaint(); return; } command = null; for (int i = 0; i < commandList.getLength(); i++) { command = (Element) commandList.item(i); String name = command.getAttribute("name"); if (name.equalsIgnoreCase(currentCommand)) { break; } } int div = splitPane.getDividerLocation(); descriptTextArea.setText(currentCommand.toUpperCase() + ": " + command.getAttribute("description")); splitPane.setBottomComponent(descriptScrollPane); splitPane.setDividerLocation(div); // The "action" tells Force Field X what to do when the // command finishes commandActions = command.getAttribute("action").trim(); // The "fileType" specifies what file types this command can execute // on String string = command.getAttribute("fileType").trim(); String[] types = string.split(" +"); commandFileTypes.clear(); for (String type : types) { if (type.contains("XYZ")) { commandFileTypes.add(FileType.XYZ); } if (type.contains("INT")) { commandFileTypes.add(FileType.INT); } if (type.contains("ARC")) { commandFileTypes.add(FileType.ARC); } if (type.contains("PDB")) { commandFileTypes.add(FileType.PDB); } if (type.contains("ANY")) { commandFileTypes.add(FileType.ANY); } } // Determine what options are available for this command options = command.getElementsByTagName("Option"); int length = options.getLength(); for (int i = 0; i < length; i++) { // This Option will be enabled (isEnabled = true) unless a // Conditional disables it boolean isEnabled = true; option = (Element) options.item(i); conditionalList = option.getElementsByTagName("Conditional"); /* * Currently, there can only be 0 or 1 Conditionals per Option * There are three types of Conditionals implemented. 1.) * Conditional on a previous Option, this option may be * available 2.) Conditional on input for this option, a * sub-option may be available 3.) Conditional on the presence * of keywords, this option may be available */ if (conditionalList != null) { conditional = (Element) conditionalList.item(0); } else { conditional = null; } // Get the command line flag String flag = option.getAttribute("flag").trim(); // Get the description String optionDescript = option.getAttribute("description"); JTextArea optionTextArea = new JTextArea(" " + optionDescript.trim()); optionTextArea.setEditable(false); optionTextArea.setLineWrap(true); optionTextArea.setWrapStyleWord(true); optionTextArea.setBorder(etchedBorder); // Get the default for this Option (if one exists) String defaultOption = option.getAttribute("default"); // Option Panel optionPanel = new JPanel(new BorderLayout()); optionPanel.add(optionTextArea, BorderLayout.NORTH); String swing = option.getAttribute("gui"); JPanel optionValuesPanel = new JPanel(new FlowLayout()); optionValuesPanel.setBorder(etchedBorder); ButtonGroup bg = null; if (swing.equalsIgnoreCase("CHECKBOXES")) { // CHECKBOXES allows selection of 1 or more values from a // predefined set (Analyze, for example) values = option.getElementsByTagName("Value"); for (int j = 0; j < values.getLength(); j++) { value = (Element) values.item(j); JCheckBox jcb = new JCheckBox(value.getAttribute("name")); jcb.addMouseListener(this); jcb.setName(flag); if (defaultOption != null && jcb.getActionCommand().equalsIgnoreCase(defaultOption)) { jcb.setSelected(true); } optionValuesPanel.add(jcb); } } else if (swing.equalsIgnoreCase("TEXTFIELD")) { // TEXTFIELD takes an arbitrary String as input JTextField jtf = new JTextField(20); jtf.addMouseListener(this); jtf.setName(flag); if (defaultOption != null && defaultOption.equals("ATOMS")) { FFXSystem sys = mainPanel.getHierarchy().getActive(); if (sys != null) { jtf.setText("" + sys.getAtomList().size()); } } else if (defaultOption != null) { jtf.setText(defaultOption); } optionValuesPanel.add(jtf); } else if (swing.equalsIgnoreCase("RADIOBUTTONS")) { // RADIOBUTTONS allows one choice from a set of predifined // values bg = new ButtonGroup(); values = option.getElementsByTagName("Value"); for (int j = 0; j < values.getLength(); j++) { value = (Element) values.item(j); JRadioButton jrb = new JRadioButton(value.getAttribute("name")); jrb.addMouseListener(this); jrb.setName(flag); bg.add(jrb); if (defaultOption != null && jrb.getActionCommand().equalsIgnoreCase(defaultOption)) { jrb.setSelected(true); } optionValuesPanel.add(jrb); } } else if (swing.equalsIgnoreCase("PROTEIN")) { // Protein allows selection of amino acids for the protein // builder optionValuesPanel.setLayout(new BoxLayout(optionValuesPanel, BoxLayout.Y_AXIS)); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); optionValuesPanel.add(getAminoAcidPanel()); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); acidComboBox.removeAllItems(); JButton add = new JButton("Edit"); add.setActionCommand("PROTEIN"); add.addActionListener(this); add.setAlignmentX(Button.CENTER_ALIGNMENT); JPanel comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); comboPanel.add(acidTextField); comboPanel.add(add); optionValuesPanel.add(comboPanel); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); JButton remove = new JButton("Remove"); add.setMinimumSize(remove.getPreferredSize()); add.setPreferredSize(remove.getPreferredSize()); remove.setActionCommand("PROTEIN"); remove.addActionListener(this); remove.setAlignmentX(Button.CENTER_ALIGNMENT); comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); comboPanel.add(acidComboBox); comboPanel.add(remove); optionValuesPanel.add(comboPanel); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); optionValuesPanel.add(acidScrollPane); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); JButton reset = new JButton("Reset"); reset.setActionCommand("PROTEIN"); reset.addActionListener(this); reset.setAlignmentX(Button.CENTER_ALIGNMENT); optionValuesPanel.add(reset); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); acidTextArea.setText(""); acidTextField.setText(""); } else if (swing.equalsIgnoreCase("NUCLEIC")) { // Nucleic allows selection of nucleic acids for the nucleic // acid builder optionValuesPanel.setLayout(new BoxLayout(optionValuesPanel, BoxLayout.Y_AXIS)); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); optionValuesPanel.add(getNucleicAcidPanel()); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); acidComboBox.removeAllItems(); JButton add = new JButton("Edit"); add.setActionCommand("NUCLEIC"); add.addActionListener(this); add.setAlignmentX(Button.CENTER_ALIGNMENT); JPanel comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); comboPanel.add(acidTextField); comboPanel.add(add); optionValuesPanel.add(comboPanel); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); JButton remove = new JButton("Remove"); add.setMinimumSize(remove.getPreferredSize()); add.setPreferredSize(remove.getPreferredSize()); remove.setActionCommand("NUCLEIC"); remove.addActionListener(this); remove.setAlignmentX(Button.CENTER_ALIGNMENT); comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); comboPanel.add(acidComboBox); comboPanel.add(remove); optionValuesPanel.add(comboPanel); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); optionValuesPanel.add(acidScrollPane); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); JButton button = new JButton("Reset"); button.setActionCommand("NUCLEIC"); button.addActionListener(this); button.setAlignmentX(Button.CENTER_ALIGNMENT); optionValuesPanel.add(button); optionValuesPanel.add(Box.createRigidArea(new Dimension(0, 5))); acidTextArea.setText(""); acidTextField.setText(""); } else if (swing.equalsIgnoreCase("SYSTEMS")) { // SYSTEMS allows selection of an open system JComboBox<FFXSystem> jcb = new JComboBox<>(mainPanel.getHierarchy().getNonActiveSystems()); jcb.setSize(jcb.getMaximumSize()); jcb.addActionListener(this); optionValuesPanel.add(jcb); } // Set up a Conditional for this Option if (conditional != null) { isEnabled = false; String conditionalName = conditional.getAttribute("name"); String conditionalValues = conditional.getAttribute("value"); String cDescription = conditional.getAttribute("description"); String cpostProcess = conditional.getAttribute("postProcess"); if (conditionalName.toUpperCase().startsWith("KEYWORD")) { optionPanel.setName(conditionalName); String keywords[] = conditionalValues.split(" +"); if (activeSystem != null) { Hashtable<String, Keyword> systemKeywords = activeSystem.getKeywords(); for (String key : keywords) { if (systemKeywords.containsKey(key.toUpperCase())) { isEnabled = true; } } } } else if (conditionalName.toUpperCase().startsWith("VALUE")) { isEnabled = true; // Add listeners to the values of this option so // the conditional options can be disabled/enabled. for (int j = 0; j < optionValuesPanel.getComponentCount(); j++) { JToggleButton jtb = (JToggleButton) optionValuesPanel.getComponent(j); jtb.addActionListener(this); jtb.setActionCommand("Conditional"); } JPanel condpanel = new JPanel(); condpanel.setBorder(etchedBorder); JLabel condlabel = new JLabel(cDescription); condlabel.setEnabled(false); condlabel.setName(conditionalValues); JTextField condtext = new JTextField(10); condlabel.setLabelFor(condtext); if (cpostProcess != null) { condtext.setName(cpostProcess); } condtext.setEnabled(false); condpanel.add(condlabel); condpanel.add(condtext); conditionals.add(condlabel); optionPanel.add(condpanel, BorderLayout.SOUTH); } else if (conditionalName.toUpperCase().startsWith("REFLECTION")) { String[] condModifiers; if (conditionalValues.equalsIgnoreCase("AltLoc")) { condModifiers = activeSystem.getAltLocations(); if (condModifiers != null && condModifiers.length > 1) { isEnabled = true; bg = new ButtonGroup(); for (int j = 0; j < condModifiers.length; j++) { JRadioButton jrbmi = new JRadioButton(condModifiers[j]); jrbmi.addMouseListener(this); bg.add(jrbmi); optionValuesPanel.add(jrbmi); if (j == 0) { jrbmi.setSelected(true); } } } } else if (conditionalValues.equalsIgnoreCase("Chains")) { condModifiers = activeSystem.getChainNames(); if (condModifiers != null && condModifiers.length > 0) { isEnabled = true; for (int j = 0; j < condModifiers.length; j++) { JRadioButton jrbmi = new JRadioButton(condModifiers[j]); jrbmi.addMouseListener(this); bg.add(jrbmi); optionValuesPanel.add(jrbmi, j); } } } } } optionPanel.add(optionValuesPanel, BorderLayout.CENTER); optionPanel.setPreferredSize(optionPanel.getPreferredSize()); optionsTabbedPane.addTab(option.getAttribute("name"), optionPanel); optionsTabbedPane.setEnabledAt(optionsTabbedPane.getTabCount() - 1, isEnabled); } } optionsTabbedPane.setPreferredSize(optionsTabbedPane.getPreferredSize()); commandPanel.setLayout(borderLayout); commandPanel.add(optionsTabbedPane, BorderLayout.CENTER); commandPanel.validate(); commandPanel.repaint(); loadLogSettings(); statusLabel.setText(" " + createCommandInput()); } private void loadLogSettings() { String selected = (String) logSettings.getSelectedItem(); logSettings.removeActionListener(this); logSettings.removeAllItems(); File currentLog; String fileName; File logDir; File systemDir; // This implies no Open System if (activeSystem == null) { fileName = ((String) currentCommandBox.getSelectedItem()).toLowerCase() + ".log"; currentLog = new File(MainPanel.getPWD() + File.separator + fileName); logDir = currentLog.getParentFile(); systemDir = MainPanel.getPWD(); } else { currentLog = activeSystem.getLogFile(); fileName = currentLog.getName(); logDir = currentLog.getParentFile(); systemDir = activeSystem.getFile().getAbsoluteFile().getParentFile(); } File tempLog; File newLog; if (logDir == null || !logDir.equals(systemDir)) { tempLog = new File(systemDir.getAbsolutePath() + File.separator + fileName); if (!commandFileTypes.contains(FileType.ANY)) { activeSystem.setLogFile(tempLog); } } else { tempLog = currentLog; } // Simple Case - default log file doesn't exist yet String createNew = null; if (!tempLog.exists()) { createNew = "Create " + fileName; logSettings.addItem(createNew); logSettings.setSelectedItem(createNew); logString = getLogString(tempLog); logSettings.addActionListener(this); if (!commandFileTypes.contains(FileType.ANY)) { activeSystem.setLogFile(tempLog); } return; } // The default log exists, so we can append to it, overwrite it, or // create a new one newLog = SystemFilter.version(tempLog); tempLog = SystemFilter.previousVersion(newLog); fileName = tempLog.getName(); String append = "Append to " + fileName; String overwrite = "Overwrite " + fileName; logSettings.addItem(append); logSettings.addItem(overwrite); if (!newLog.equals(tempLog)) { createNew = "Create " + newLog.getName(); logSettings.addItem(createNew); } if (selected == null) { logSettings.setSelectedIndex(0); logString = null; } else if (selected.startsWith("Append")) { logSettings.setSelectedItem(append); logString = getLogString(tempLog); } else if (selected.startsWith("Overwrite")) { logSettings.setSelectedItem(overwrite); logString = getLogString(tempLog); } else { if (createNew != null) { logSettings.setSelectedItem(createNew); logString = getLogString(newLog); } else { logString = getLogString(tempLog); logSettings.setSelectedItem(append); } } logSettings.addActionListener(this); } /** * Mouse events are used to trigger status bar updates. * * {@inheritDoc} */ @Override public void mouseClicked(MouseEvent evt) { statusLabel.setText(" " + createCommandInput()); } /** * {@inheritDoc} */ @Override public void mouseEntered(MouseEvent evt) { mouseClicked(evt); } /** * {@inheritDoc} */ @Override public void mouseExited(MouseEvent evt) { mouseClicked(evt); } /** * {@inheritDoc} */ @Override public void mousePressed(MouseEvent evt) { mouseClicked(evt); } /** * {@inheritDoc} */ @Override public void mouseReleased(MouseEvent evt) { mouseClicked(evt); } /** * If a TINKER END file exists for the active system & command, remove it. */ private void removeEnd() { FFXSystem m = mainPanel.getHierarchy().getActive(); if (m == null) { return; } File f = m.getFile(); if (f == null) { return; } File end = null; try { if (f.getName().indexOf(".") > 0) { String name = f.getName().substring(0, f.getName().lastIndexOf(".")); end = new File(f.getParent(), name + ".end"); } else { end = new File(f.getParent(), f.getName() + ".end"); } } catch (Exception e) { } if (end != null && end.exists()) { end.delete(); } } /** * Save ModelingPanel user preferences */ public void savePrefs() { String c = ModelingPanel.class.getName(); prefs.putBoolean(c + ".description", descriptCheckBox.isSelected()); } /** ********************************************************************** */ // Initialization code and misc. methods. public void selected() { loadLogSettings(); setDivider(descriptCheckBox.isSelected()); validate(); repaint(); } /** * <p> * setCommand</p> * * @param command a {@link java.lang.String} object. * @return a boolean. */ public boolean setCommand(String command) { if (command == null) { return false; } command = command.toLowerCase(); command = command.replaceFirst(command.substring(0, 1), command.toUpperCase().substring(0, 1)); currentCommandBox.setSelectedItem(command); mainPanel.setPanel(MainPanel.MODELING); return currentCommandBox.getSelectedItem().equals(command); } /** * Set the description divider location * * @param showDescription True to show the command description */ private void setDivider(boolean showDescription) { descriptCheckBox.setSelected(showDescription); if (showDescription) { int spDivider = (int) (this.getHeight() * (3.0f / 5.0f)); splitPane.setDividerLocation(spDivider); } else { splitPane.setDividerLocation(1.0); } } /** * Prompt the user to toggle the existence of a TINKER END file. */ private void setEnd() { if (ffxThread != null && ffxThread.isAlive()) { ModelingShell modelingShell = mainPanel.getModelingShell(); modelingShell.doInterrupt(); } } /** ********************************************************************** * * @param mode a {@link java.lang.String} object. */ // Logging Configuation public void setLogMode(String mode) { mode = mode.toUpperCase(); for (int i = 0; i < logSettings.getItemCount(); i++) { String logType = (String) logSettings.getItemAt(i); if (logType.toUpperCase().startsWith(mode)) { logSettings.setSelectedIndex(i); break; } } loadLogSettings(); } /** * <p> * deleteLogs</p> */ public void deleteLogs() { if (activeSystem != null) { File file = activeSystem.getFile(); String name = file.getName(); String dir = file.getParent(); int i = JOptionPane.showConfirmDialog(this, "Delete all logs for " + name + " from " + dir + " ?", "Delete Logs", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (i == JOptionPane.YES_OPTION) { try { File files[] = activeSystem.getFile().getParentFile().listFiles(); for (File f : files) { name = FilenameUtils.getBaseName(f.getAbsolutePath()); if (FilenameUtils.wildcardMatch(f.getName(), name + ".log*")) { f.delete(); } } } catch (Exception e) { } activeSystem.setLogFile(null); loadLogSettings(); } } } /** * <p> * toString</p> * * @return a {@link java.lang.String} object. */ @Override public String toString() { return "Modeling Panel"; } }