Mercurial > repos > timpalpant > java_genomics_toolkit
comparison gui/edu/unc/genomics/JobConfigPanel.java @ 2:e16016635b2a
Uploaded
| author | timpalpant |
|---|---|
| date | Mon, 13 Feb 2012 22:12:06 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:a54db233ee3d | 2:e16016635b2a |
|---|---|
| 1 package edu.unc.genomics; | |
| 2 | |
| 3 import java.awt.Color; | |
| 4 import java.awt.Component; | |
| 5 import java.awt.Dimension; | |
| 6 import java.awt.FileDialog; | |
| 7 import java.awt.event.ActionEvent; | |
| 8 import java.awt.event.ActionListener; | |
| 9 import java.lang.reflect.Field; | |
| 10 import java.nio.file.Path; | |
| 11 import java.util.HashMap; | |
| 12 import java.util.List; | |
| 13 import java.util.Map; | |
| 14 | |
| 15 import javax.swing.BorderFactory; | |
| 16 import javax.swing.BoxLayout; | |
| 17 import javax.swing.ImageIcon; | |
| 18 import javax.swing.JButton; | |
| 19 import javax.swing.JComboBox; | |
| 20 import javax.swing.JComponent; | |
| 21 import javax.swing.JFileChooser; | |
| 22 import javax.swing.JFrame; | |
| 23 import javax.swing.JLabel; | |
| 24 import javax.swing.JPanel; | |
| 25 import javax.swing.JTextField; | |
| 26 import javax.swing.SpringLayout; | |
| 27 import javax.swing.SwingUtilities; | |
| 28 import javax.swing.event.DocumentEvent; | |
| 29 import javax.swing.event.DocumentListener; | |
| 30 import javax.swing.layout.SpringUtilities; | |
| 31 import javax.swing.text.BadLocationException; | |
| 32 import javax.swing.text.Document; | |
| 33 | |
| 34 import org.apache.commons.lang3.StringUtils; | |
| 35 import org.apache.log4j.Logger; | |
| 36 | |
| 37 import com.beust.jcommander.ParameterDescription; | |
| 38 | |
| 39 import edu.unc.genomics.io.IntervalFile; | |
| 40 import edu.unc.genomics.io.WigFile; | |
| 41 | |
| 42 /** | |
| 43 * View for configuring the parameters of a Job | |
| 44 * Implements databinding between a Job object and the various Swing components | |
| 45 * for configuring each parameter | |
| 46 * | |
| 47 * @author timpalpant | |
| 48 * | |
| 49 */ | |
| 50 public class JobConfigPanel extends JPanel { | |
| 51 | |
| 52 private static final long serialVersionUID = 3336295203155728629L; | |
| 53 private static final Logger log = Logger.getLogger(JobConfigPanel.class); | |
| 54 | |
| 55 private static final ImageIcon fileIcon = new ImageIcon(ResourceManager.getImagesDirectory().resolve("folder_page.png").toString()); | |
| 56 | |
| 57 /** | |
| 58 * Maps parameters in the Job to GUI components (forward data-binding) | |
| 59 */ | |
| 60 private Map<ParameterDescription, JComponent> guiMap = new HashMap<>(); | |
| 61 | |
| 62 /** | |
| 63 * Maps GUI components to parameters in the Job (reverse data-binding) | |
| 64 */ | |
| 65 private Map<Component, ParameterDescription> jobMap = new HashMap<>(); | |
| 66 | |
| 67 /** | |
| 68 * The model for the Job that this panel allows you to configure | |
| 69 */ | |
| 70 private Job job; | |
| 71 | |
| 72 /** | |
| 73 * Initialize a new ConfigurationPanel with no Job | |
| 74 */ | |
| 75 public JobConfigPanel() { | |
| 76 this(null); | |
| 77 } | |
| 78 | |
| 79 /** | |
| 80 * Initialize a new ConfigurationPanel for the given Job | |
| 81 * @param job | |
| 82 */ | |
| 83 public JobConfigPanel(final Job job) { | |
| 84 setJob(job); | |
| 85 setLayout(new SpringLayout()); | |
| 86 } | |
| 87 | |
| 88 /** | |
| 89 * Return the Job that this ConfigurationPanel is editing | |
| 90 * @return | |
| 91 */ | |
| 92 public Job getJob() { | |
| 93 return job; | |
| 94 } | |
| 95 | |
| 96 /** | |
| 97 * Set the job for this Configuration panel and re-render | |
| 98 * @param job | |
| 99 */ | |
| 100 public void setJob(final Job job) { | |
| 101 this.job = job; | |
| 102 renderJob(); | |
| 103 } | |
| 104 | |
| 105 /** | |
| 106 * Highlights fields on the Panel that are not set correctly | |
| 107 */ | |
| 108 public void highlightInvalidArguments() { | |
| 109 for (ParameterDescription param : job) { | |
| 110 JComponent guiComponent = guiMap.get(param); | |
| 111 if (param.getParameter().required() && !job.isSet(param)) { | |
| 112 guiComponent.setBorder(BorderFactory.createLineBorder(Color.RED)); | |
| 113 } else { | |
| 114 guiComponent.setBorder(BorderFactory.createEmptyBorder()); | |
| 115 } | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 /** | |
| 120 * Render the parameters from the Job into GUI components | |
| 121 * and set up one-way data binding to map changes to the GUI fields | |
| 122 * back into the Job object's parameters | |
| 123 */ | |
| 124 private void renderJob() { | |
| 125 removeAll(); | |
| 126 guiMap.clear(); | |
| 127 jobMap.clear(); | |
| 128 if (job == null) { | |
| 129 validate(); | |
| 130 repaint(); | |
| 131 return; | |
| 132 } | |
| 133 | |
| 134 // Iterate through the parameters in the Job | |
| 135 // and render them appropriately based on their type | |
| 136 for (ParameterDescription paramDescription : job) { | |
| 137 // Add the parameter name to the configuration panel | |
| 138 String name = paramDescription.getLongestName(); | |
| 139 while (name.startsWith("-")) { | |
| 140 name = name.substring(1); | |
| 141 } | |
| 142 name = StringUtils.capitalize(name); | |
| 143 JLabel label = new JLabel(name); | |
| 144 label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); | |
| 145 add(label); | |
| 146 | |
| 147 // Add a panel for configuring the parameter | |
| 148 JPanel fieldPanel = new JPanel(); | |
| 149 fieldPanel.setLayout(new BoxLayout(fieldPanel, BoxLayout.LINE_AXIS)); | |
| 150 add(fieldPanel); | |
| 151 Field field = paramDescription.getField(); | |
| 152 Class<?> type = field.getType(); | |
| 153 if (type.equals(Assembly.class)) { | |
| 154 List<Assembly> availableAssemblies = AssemblyManager.getAvailableAssemblies(); | |
| 155 Assembly[] assemblies = new Assembly[availableAssemblies.size()]; | |
| 156 assemblies = availableAssemblies.toArray(assemblies); | |
| 157 final JComboBox<Assembly> cbAssemblyChooser = new JComboBox<Assembly>(assemblies); | |
| 158 cbAssemblyChooser.setPreferredSize(new Dimension(0, 25)); | |
| 159 cbAssemblyChooser.setMaximumSize(new Dimension(Integer.MAX_VALUE, cbAssemblyChooser.getPreferredSize().height)); | |
| 160 cbAssemblyChooser.setSelectedItem(AssemblyManager.getLastUsed()); | |
| 161 cbAssemblyChooser.addActionListener(new ActionListener() { | |
| 162 public void actionPerformed(ActionEvent e) { | |
| 163 log.debug("Auto-databinding changed assembly into Job argument"); | |
| 164 Assembly selectedAssembly = (Assembly) cbAssemblyChooser.getSelectedItem(); | |
| 165 AssemblyManager.setLastUsed(selectedAssembly); | |
| 166 ParameterDescription param = jobMap.get(cbAssemblyChooser); | |
| 167 job.setArgument(param, selectedAssembly.toString()); | |
| 168 } | |
| 169 }); | |
| 170 fieldPanel.add(cbAssemblyChooser); | |
| 171 guiMap.put(paramDescription, cbAssemblyChooser); | |
| 172 jobMap.put(cbAssemblyChooser, paramDescription); | |
| 173 } else { | |
| 174 final JTextField textField = new JTextField(); | |
| 175 // Set to default parameter, if it exists | |
| 176 if (job.isSet(paramDescription)) { | |
| 177 textField.setText(job.getArgument(paramDescription)); | |
| 178 } | |
| 179 textField.setPreferredSize(new Dimension(0, 20)); | |
| 180 textField.setMaximumSize(new Dimension(Integer.MAX_VALUE, textField.getPreferredSize().height)); | |
| 181 textField.getDocument().addDocumentListener(new DocumentListener() { | |
| 182 public void changedUpdate(DocumentEvent e) { | |
| 183 pushTextToModel(e); | |
| 184 } | |
| 185 | |
| 186 public void removeUpdate(DocumentEvent e) { | |
| 187 pushTextToModel(e); | |
| 188 } | |
| 189 | |
| 190 public void insertUpdate(DocumentEvent e) { | |
| 191 pushTextToModel(e); | |
| 192 } | |
| 193 | |
| 194 private void pushTextToModel(DocumentEvent e) { | |
| 195 log.debug("Auto-databinding changed text into Job argument"); | |
| 196 Document doc = (Document) e.getDocument(); | |
| 197 ParameterDescription param = jobMap.get(textField); | |
| 198 try { | |
| 199 String text = doc.getText(0, doc.getLength()); | |
| 200 job.setArgument(param, text); | |
| 201 } catch (BadLocationException e1) { | |
| 202 log.error("Error pushing changed text into Job model"); | |
| 203 e1.printStackTrace(); | |
| 204 } | |
| 205 } | |
| 206 }); | |
| 207 fieldPanel.add(textField); | |
| 208 guiMap.put(paramDescription, textField); | |
| 209 jobMap.put(textField, paramDescription); | |
| 210 | |
| 211 // For input/output files, add a file chooser button | |
| 212 if (type.equals(Path.class) || type.equals(WigFile.class) || type.equals(IntervalFile.class)) { | |
| 213 // TODO Replace with file icon | |
| 214 JButton btnChooseFile = new JButton(fileIcon); | |
| 215 btnChooseFile.addActionListener(new ActionListener() { | |
| 216 public void actionPerformed(ActionEvent e) { | |
| 217 // AWT FileDialog uses native components, but seems to hang | |
| 218 //Component c = (Component) e.getSource(); | |
| 219 //JFrame frame = (JFrame) SwingUtilities.getRoot(c); | |
| 220 //FileDialog fd = new FileDialog(frame, "Choose File"); | |
| 221 //fd.setVisible(true); | |
| 222 //if (fd.getFile() != null) { | |
| 223 // textField.setText(fd.getDirectory()+fd.getFile()); | |
| 224 //} | |
| 225 | |
| 226 // Swing JFileChooser | |
| 227 JFileChooser fc = new JFileChooser(); | |
| 228 int retValue = fc.showDialog(getParent(), "OK"); | |
| 229 if (retValue == JFileChooser.APPROVE_OPTION) { | |
| 230 textField.setText(fc.getSelectedFile().toString()); | |
| 231 } | |
| 232 } | |
| 233 }); | |
| 234 fieldPanel.add(btnChooseFile); | |
| 235 } | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 // Lay out the panel | |
| 240 SpringUtilities.makeCompactGrid(this, job.numParameters(), 2, 5, 5, 5, 5); | |
| 241 | |
| 242 validate(); | |
| 243 repaint(); | |
| 244 } | |
| 245 | |
| 246 } |
