Mercurial > repos > timpalpant > java_genomics_toolkit
view java-genomics-toolkit/gui/edu/unc/genomics/JobConfigPanel.java @ 0:1daf3026d231
Upload alpha version
author | timpalpant |
---|---|
date | Mon, 13 Feb 2012 21:55:55 -0500 |
parents | |
children |
line wrap: on
line source
package edu.unc.genomics; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FileDialog; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.Field; import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SpringLayout; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.layout.SpringUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import com.beust.jcommander.ParameterDescription; import edu.unc.genomics.io.IntervalFile; import edu.unc.genomics.io.WigFile; /** * View for configuring the parameters of a Job * Implements databinding between a Job object and the various Swing components * for configuring each parameter * * @author timpalpant * */ public class JobConfigPanel extends JPanel { private static final long serialVersionUID = 3336295203155728629L; private static final Logger log = Logger.getLogger(JobConfigPanel.class); private static final ImageIcon fileIcon = new ImageIcon(ResourceManager.getImagesDirectory().resolve("folder_page.png").toString()); /** * Maps parameters in the Job to GUI components (forward data-binding) */ private Map<ParameterDescription, JComponent> guiMap = new HashMap<>(); /** * Maps GUI components to parameters in the Job (reverse data-binding) */ private Map<Component, ParameterDescription> jobMap = new HashMap<>(); /** * The model for the Job that this panel allows you to configure */ private Job job; /** * Initialize a new ConfigurationPanel with no Job */ public JobConfigPanel() { this(null); } /** * Initialize a new ConfigurationPanel for the given Job * @param job */ public JobConfigPanel(final Job job) { setJob(job); setLayout(new SpringLayout()); } /** * Return the Job that this ConfigurationPanel is editing * @return */ public Job getJob() { return job; } /** * Set the job for this Configuration panel and re-render * @param job */ public void setJob(final Job job) { this.job = job; renderJob(); } /** * Highlights fields on the Panel that are not set correctly */ public void highlightInvalidArguments() { for (ParameterDescription param : job) { JComponent guiComponent = guiMap.get(param); if (param.getParameter().required() && !job.isSet(param)) { guiComponent.setBorder(BorderFactory.createLineBorder(Color.RED)); } else { guiComponent.setBorder(BorderFactory.createEmptyBorder()); } } } /** * Render the parameters from the Job into GUI components * and set up one-way data binding to map changes to the GUI fields * back into the Job object's parameters */ private void renderJob() { removeAll(); guiMap.clear(); jobMap.clear(); if (job == null) { validate(); repaint(); return; } // Iterate through the parameters in the Job // and render them appropriately based on their type for (ParameterDescription paramDescription : job) { // Add the parameter name to the configuration panel String name = paramDescription.getLongestName(); while (name.startsWith("-")) { name = name.substring(1); } name = StringUtils.capitalize(name); JLabel label = new JLabel(name); label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); add(label); // Add a panel for configuring the parameter JPanel fieldPanel = new JPanel(); fieldPanel.setLayout(new BoxLayout(fieldPanel, BoxLayout.LINE_AXIS)); add(fieldPanel); Field field = paramDescription.getField(); Class<?> type = field.getType(); if (type.equals(Assembly.class)) { List<Assembly> availableAssemblies = AssemblyManager.getAvailableAssemblies(); Assembly[] assemblies = new Assembly[availableAssemblies.size()]; assemblies = availableAssemblies.toArray(assemblies); final JComboBox<Assembly> cbAssemblyChooser = new JComboBox<Assembly>(assemblies); cbAssemblyChooser.setPreferredSize(new Dimension(0, 25)); cbAssemblyChooser.setMaximumSize(new Dimension(Integer.MAX_VALUE, cbAssemblyChooser.getPreferredSize().height)); cbAssemblyChooser.setSelectedItem(AssemblyManager.getLastUsed()); cbAssemblyChooser.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { log.debug("Auto-databinding changed assembly into Job argument"); Assembly selectedAssembly = (Assembly) cbAssemblyChooser.getSelectedItem(); AssemblyManager.setLastUsed(selectedAssembly); ParameterDescription param = jobMap.get(cbAssemblyChooser); job.setArgument(param, selectedAssembly.toString()); } }); fieldPanel.add(cbAssemblyChooser); guiMap.put(paramDescription, cbAssemblyChooser); jobMap.put(cbAssemblyChooser, paramDescription); } else { final JTextField textField = new JTextField(); // Set to default parameter, if it exists if (job.isSet(paramDescription)) { textField.setText(job.getArgument(paramDescription)); } textField.setPreferredSize(new Dimension(0, 20)); textField.setMaximumSize(new Dimension(Integer.MAX_VALUE, textField.getPreferredSize().height)); textField.getDocument().addDocumentListener(new DocumentListener() { public void changedUpdate(DocumentEvent e) { pushTextToModel(e); } public void removeUpdate(DocumentEvent e) { pushTextToModel(e); } public void insertUpdate(DocumentEvent e) { pushTextToModel(e); } private void pushTextToModel(DocumentEvent e) { log.debug("Auto-databinding changed text into Job argument"); Document doc = (Document) e.getDocument(); ParameterDescription param = jobMap.get(textField); try { String text = doc.getText(0, doc.getLength()); job.setArgument(param, text); } catch (BadLocationException e1) { log.error("Error pushing changed text into Job model"); e1.printStackTrace(); } } }); fieldPanel.add(textField); guiMap.put(paramDescription, textField); jobMap.put(textField, paramDescription); // For input/output files, add a file chooser button if (type.equals(Path.class) || type.equals(WigFile.class) || type.equals(IntervalFile.class)) { // TODO Replace with file icon JButton btnChooseFile = new JButton(fileIcon); btnChooseFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // AWT FileDialog uses native components, but seems to hang //Component c = (Component) e.getSource(); //JFrame frame = (JFrame) SwingUtilities.getRoot(c); //FileDialog fd = new FileDialog(frame, "Choose File"); //fd.setVisible(true); //if (fd.getFile() != null) { // textField.setText(fd.getDirectory()+fd.getFile()); //} // Swing JFileChooser JFileChooser fc = new JFileChooser(); int retValue = fc.showDialog(getParent(), "OK"); if (retValue == JFileChooser.APPROVE_OPTION) { textField.setText(fc.getSelectedFile().toString()); } } }); fieldPanel.add(btnChooseFile); } } } // Lay out the panel SpringUtilities.makeCompactGrid(this, job.numParameters(), 2, 5, 5, 5, 5); validate(); repaint(); } }