3 import jalview.ws.params.OptionI;
4 import jalview.ws.params.ParameterI;
5 import jalview.ws.params.ValueConstrainI;
7 import java.awt.BorderLayout;
8 import java.awt.Component;
9 import java.awt.Container;
10 import java.awt.Dimension;
11 import java.awt.FlowLayout;
13 import java.awt.GridLayout;
14 import java.awt.Rectangle;
15 import java.awt.event.ActionEvent;
16 import java.awt.event.ActionListener;
17 import java.awt.event.MouseEvent;
18 import java.awt.event.MouseListener;
20 import java.util.Hashtable;
21 import java.util.List;
24 import javax.swing.JButton;
25 import javax.swing.JCheckBox;
26 import javax.swing.JComboBox;
27 import javax.swing.JComponent;
28 import javax.swing.JLabel;
29 import javax.swing.JMenuItem;
30 import javax.swing.JPanel;
31 import javax.swing.JPopupMenu;
32 import javax.swing.JScrollPane;
33 import javax.swing.JSlider;
34 import javax.swing.JTextArea;
35 import javax.swing.JTextField;
36 import javax.swing.border.TitledBorder;
37 import javax.swing.event.ChangeEvent;
38 import javax.swing.event.ChangeListener;
40 import compbio.metadata.ValueConstrain.Type;
43 * GUI generator/manager for options and parameters. Originally abstracted from the WsJobParameters dialog box.
47 public class OptsAndParamsPage
49 public class OptionBox extends JPanel implements MouseListener,
52 JCheckBox enabled = new JCheckBox();
56 boolean hasLink = false;
58 boolean initEnabled = false;
60 String initVal = null;
64 JLabel optlabel = new JLabel();
66 JComboBox val = new JComboBox();
68 public OptionBox(OptionI opt)
71 setLayout(new BorderLayout());
72 enabled.setSelected(opt.isRequired()); // TODO: lock required options
73 enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
75 enabled.setText(opt.getName());
76 enabled.addActionListener(this);
77 finfo = option.getFurtherDetails();
81 enabled.setToolTipText("<html>"
82 + JvSwingUtils.wrapTooltip(opt.getDescription()
83 + "<br><img src=\"" + linkImageURL + "\"/>")
85 enabled.addMouseListener(this);
89 enabled.setToolTipText("<html>"
90 + JvSwingUtils.wrapTooltip(opt.getDescription())
93 add(enabled, BorderLayout.NORTH);
94 if (opt.getPossibleValues().size() > 1)
96 setLayout(new GridLayout(1, 2));
97 for (Object str : opt.getPossibleValues())
99 val.addItem((String) str);
101 val.setSelectedItem((String) opt.getDefaultValue());
102 val.addActionListener(this);
103 add(val, BorderLayout.SOUTH);
105 // TODO: add actionListeners for popup (to open further info),
106 // and to update list of parameters if an option is enabled
107 // that takes a value. JBPNote: is this TODO still valid ?
111 public void actionPerformed(ActionEvent e)
113 if (e.getSource() != enabled)
115 enabled.setSelected(true);
120 private void checkIfModified()
122 boolean notmod = (initEnabled == enabled.isSelected());
123 if (enabled.isSelected())
127 notmod &= initVal.equals(val.getSelectedItem());
131 // compare against default service setting
132 notmod &= option.getDefaultValue() == null
133 || option.getDefaultValue().equals(val.getSelectedItem());
138 notmod &= initVal == null;
140 poparent.argSetModified(this, !notmod);
143 public OptionI getOptionIfEnabled()
145 if (!enabled.isSelected())
149 OptionI opt = option.copy();
151 if (val.getSelectedItem() != null)
153 opt.setDefaultValue((String) val.getSelectedItem());
158 public void mouseClicked(MouseEvent e)
160 if (javax.swing.SwingUtilities.isRightMouseButton(e))
162 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
166 public void mouseEntered(MouseEvent e)
168 // TODO Auto-generated method stub
172 public void mouseExited(MouseEvent e)
174 // TODO Auto-generated method stub
178 public void mousePressed(MouseEvent e)
180 // TODO Auto-generated method stub
184 public void mouseReleased(MouseEvent e)
186 // TODO Auto-generated method stub
190 public void resetToDefault()
192 enabled.setSelected(false);
193 if (option.isRequired())
195 // Apply default value
196 selectOption(option, option.getDefaultValue());
200 public void setInitialValue()
202 initEnabled = enabled.isSelected();
203 if (option.getPossibleValues() != null
204 && option.getPossibleValues().size() > 1)
206 initVal = (String) val.getSelectedItem();
210 initVal = (initEnabled) ? option.getDefaultValue() : null;
216 public class ParamBox extends JPanel implements ChangeListener,
217 ActionListener, MouseListener
219 boolean adjusting = false;
221 boolean choice = false;
225 JPanel controlPanel = new JPanel();
227 boolean descisvisible = false;
229 JScrollPane descPanel = new JScrollPane();
233 boolean integ = false;
237 ParameterI parameter;
239 final OptsParametersContainerI pmdialogbox;
241 JPanel settingPanel = new JPanel();
243 JButton showDesc = new JButton();
245 JSlider slider = null;
247 JTextArea string = new JTextArea();
249 ValueConstrainI validator = null;
251 JTextField valueField = null;
253 public ParamBox(final OptsParametersContainerI pmlayout, ParameterI parm)
255 pmdialogbox = pmlayout;
256 setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT));
257 setBorder(new TitledBorder(parm.getName()));
259 showDesc.setFont(new Font("Verdana", Font.PLAIN, 6));
260 showDesc.setText("+");
261 string.setFont(new Font("Verdana", Font.PLAIN, 11));
262 string.setBackground(getBackground());
264 string.setEditable(false);
265 descPanel.getViewport().setView(string);
267 descPanel.setVisible(false);
269 final ParamBox me = this;
270 finfo = parm.getFurtherDetails();
273 showDesc.setToolTipText("<html>"
275 .wrapTooltip("Click to show brief description<br><img src=\""
277 + "\"/> Right click for further information.")
279 showDesc.addMouseListener(this);
283 showDesc.setToolTipText("<html>"
285 .wrapTooltip("Click to show brief description.")
288 showDesc.addActionListener(new ActionListener()
291 public void actionPerformed(ActionEvent e)
293 descisvisible = !descisvisible;
294 descPanel.setVisible(descisvisible);
295 descPanel.getVerticalScrollBar().setValue(0);
296 me.setPreferredSize(new Dimension(PARAM_WIDTH,
297 (descisvisible) ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT));
299 pmlayout.refreshParamLayout();
302 string.setWrapStyleWord(true);
303 string.setLineWrap(true);
304 string.setColumns(32);
305 string.setText(parm.getDescription());
306 JPanel firstrow = new JPanel();
307 firstrow.setLayout(null);
308 controlPanel.setLayout(new BorderLayout());
309 controlPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
310 PARAM_CLOSEDHEIGHT - 50));
311 showDesc.setBounds(new Rectangle(10, 10, 16, 16));
312 firstrow.add(showDesc);
313 firstrow.add(controlPanel);
314 firstrow.setBounds(new Rectangle(10, 20, PARAM_WIDTH - 30,
315 PARAM_CLOSEDHEIGHT - 30));
317 validator = parm.getValidValue();
319 if (validator != null)
321 integ = validator.getType() == Type.Integer;
325 if (parameter.getPossibleValues() != null)
330 updateControls(parm);
331 descPanel.setBounds(new Rectangle(10, PARAM_CLOSEDHEIGHT,
332 PARAM_WIDTH - 20, PARAM_HEIGHT - PARAM_CLOSEDHEIGHT - 5));
337 public void actionPerformed(ActionEvent e)
345 updateSliderFromValueField();
350 private void checkIfModified()
352 Object cstate = updateSliderFromValueField();
353 boolean notmod = false;
354 if (cstate.getClass() == lastVal.getClass())
356 if (cstate instanceof int[])
358 notmod = (((int[]) cstate)[0] == ((int[]) lastVal)[0]);
360 else if (cstate instanceof float[])
362 notmod = (((float[]) cstate)[0] == ((float[]) lastVal)[0]);
364 else if (cstate instanceof String[])
366 notmod = (((String[]) cstate)[0].equals(((String[]) lastVal)[0]));
369 pmdialogbox.argSetModified(this, !notmod);
373 public int getBaseline(int width, int height) {
377 // from http://stackoverflow.com/questions/2743177/top-alignment-for-flowlayout
378 // helpful hint of using the Java 1.6 alignBaseLine property of FlowLayout
380 public Component.BaselineResizeBehavior getBaselineResizeBehavior() {
381 return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
384 public int getBoxHeight()
386 return (descisvisible ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT);
389 public ParameterI getParameter()
391 ParameterI prm = parameter.copy();
394 prm.setDefaultValue((String) choicebox.getSelectedItem());
398 prm.setDefaultValue(valueField.getText());
405 // reset the widget's initial value.
409 public void mouseClicked(MouseEvent e)
411 if (javax.swing.SwingUtilities.isRightMouseButton(e))
413 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
417 public void mouseEntered(MouseEvent e)
419 // TODO Auto-generated method stub
423 public void mouseExited(MouseEvent e)
425 // TODO Auto-generated method stub
429 public void mousePressed(MouseEvent e)
431 // TODO Auto-generated method stub
435 public void mouseReleased(MouseEvent e)
437 // TODO Auto-generated method stub
441 public void stateChanged(ChangeEvent e)
445 valueField.setText(""
446 + ((integ) ? ("" + (int) slider.getValue())
447 : ("" + (float) (slider.getValue() / 1000f))));
452 public void updateControls(ParameterI parm)
455 boolean init = (choicebox == null && valueField == null);
460 choicebox = new JComboBox();
461 choicebox.addActionListener(this);
462 controlPanel.add(choicebox, BorderLayout.CENTER);
466 slider = new JSlider();
467 slider.addChangeListener(this);
468 valueField = new JTextField();
469 valueField.addActionListener(this);
470 valueField.setPreferredSize(new Dimension(60, 25));
471 controlPanel.add(slider, BorderLayout.WEST);
472 controlPanel.add(valueField, BorderLayout.EAST);
483 List vals = parm.getPossibleValues();
484 for (Object val : vals)
486 choicebox.addItem(val);
490 if (parm.getDefaultValue() != null)
492 choicebox.setSelectedItem(parm.getDefaultValue());
497 valueField.setText(parm.getDefaultValue());
500 lastVal = updateSliderFromValueField();
504 public Object updateSliderFromValueField()
508 if (validator != null)
515 valueField.setText(valueField.getText().trim());
516 iVal = Integer.valueOf(valueField.getText());
517 if (validator.getMin() != null
518 && validator.getMin().intValue() > iVal)
520 iVal = validator.getMin().intValue();
521 // TODO: provide visual indication that hard limit was reached for
524 if (validator.getMax() != null
525 && validator.getMax().intValue() < iVal)
527 iVal = validator.getMax().intValue();
528 // TODO: provide visual indication that hard limit was reached for
531 } catch (Exception e)
535 if (validator.getMin() != null && validator.getMax() != null)
537 slider.getModel().setRangeProperties(iVal, 1,
538 validator.getMin().intValue(),
539 validator.getMax().intValue(), true);
543 slider.setVisible(false);
553 fVal = Float.valueOf(valueField.getText());
554 if (validator.getMin() != null
555 && validator.getMin().floatValue() > fVal)
557 fVal = validator.getMin().floatValue();
558 // TODO: provide visual indication that hard limit was reached for
561 if (validator.getMax() != null
562 && validator.getMax().floatValue() < fVal)
564 fVal = validator.getMax().floatValue();
565 // TODO: provide visual indication that hard limit was reached for
568 } catch (Exception e)
572 if (validator.getMin() != null && validator.getMax() != null)
574 slider.getModel().setRangeProperties((int) fVal * 1000, 1,
575 (int) validator.getMin().floatValue() * 1000,
576 (int) validator.getMax().floatValue() * 1000, true);
580 slider.setVisible(false);
590 slider.setVisible(false);
592 { valueField.getText().trim() };
597 { (String) choicebox.getSelectedItem() };
604 static final int PARAM_WIDTH = 340;
606 private static final int PARAM_HEIGHT = 150;
608 static final int PARAM_CLOSEDHEIGHT = 80;
609 public OptsAndParamsPage(OptsParametersContainerI wsJobParameters)
611 poparent = wsJobParameters;
614 public static void showUrlPopUp(JComponent invoker, final String finfo,
618 JPopupMenu mnu = new JPopupMenu();
619 JMenuItem mitem = new JMenuItem("View " + finfo);
620 mitem.addActionListener(new ActionListener()
624 public void actionPerformed(ActionEvent e)
626 Desktop.showUrl(finfo);
631 mnu.show(invoker, x, y);
635 URL linkImageURL = getClass().getResource("/images/link.gif");
637 Map<String, OptionBox> optSet = new Hashtable<String, OptionBox>();
639 Map<String, ParamBox> paramSet = new Hashtable<String, ParamBox>();
641 public Map<String, OptionBox> getOptSet()
646 public void setOptSet(Map<String, OptionBox> optSet)
648 this.optSet = optSet;
651 public Map<String, ParamBox> getParamSet()
656 public void setParamSet(Map<String, ParamBox> paramSet)
658 this.paramSet = paramSet;
662 OptsParametersContainerI poparent;
664 OptionBox addOption(OptionI opt)
666 OptionBox cb = optSet.get(opt.getName());
669 cb = new OptionBox(opt);
670 optSet.put(opt.getName(), cb);
671 // jobOptions.add(cb, FlowLayout.LEFT);
676 ParamBox addParameter(ParameterI arg)
678 ParamBox pb = paramSet.get(arg.getName());
681 pb = new ParamBox(poparent, arg);
682 paramSet.put(arg.getName(), pb);
683 // paramList.add(pb);
686 // take the defaults from the parameter
687 pb.updateControls(arg);
691 void selectOption(OptionI option, String string)
693 OptionBox cb = optSet.get(option.getName());
696 cb = addOption(option);
698 cb.enabled.setSelected(string != null); // initial state for an option.
701 if (option.getPossibleValues().contains(string))
703 cb.val.setSelectedItem(string);
707 throw new Error("Invalid value " + string + " for option " + option);
711 if (option.isRequired() && !cb.enabled.isSelected())
713 // TODO: indicate paramset is not valid.. option needs to be selected!
715 cb.setInitialValue();
718 void setParameter(ParameterI arg)
720 ParamBox pb = paramSet.get(arg.getName());
727 pb.updateControls(arg);