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 } |