Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.gui

File OptsAndParamsPage.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

150
351
52
3
1,247
915
154
0.44
6.75
17.33
2.96

Classes

Class Line # Actions
OptsAndParamsPage 90 65 29
0.00%
OptsAndParamsPage.OptionBox 115 58 36
0.00%
OptsAndParamsPage.ParamBox 342 228 89
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.bin.Cache;
24    import jalview.io.DataSourceType;
25    import jalview.io.FileLoader;
26    import jalview.io.JalviewFileChooser;
27    import jalview.io.JalviewFileView;
28    import jalview.util.MessageManager;
29    import jalview.ws.jws2.dm.JabaOption;
30    import jalview.ws.params.ArgumentI;
31    import jalview.ws.params.OptionI;
32    import jalview.ws.params.ParameterI;
33    import jalview.ws.params.ValueConstrainI;
34    import jalview.ws.params.ValueConstrainI.ValueType;
35    import jalview.ws.params.simple.FileParameter;
36    import jalview.ws.params.simple.LogarithmicParameter;
37    import jalview.ws.params.simple.RadioChoiceParameter;
38    import jalview.ws.params.simple.StringParameter;
39    import java.awt.BorderLayout;
40    import java.awt.Color;
41    import java.awt.Component;
42    import java.awt.Container;
43    import java.awt.Dimension;
44    import java.awt.FlowLayout;
45    import java.awt.Font;
46    import java.awt.Rectangle;
47    import java.awt.event.ActionEvent;
48    import java.awt.event.ActionListener;
49    import java.awt.event.FocusAdapter;
50    import java.awt.event.FocusEvent;
51    import java.awt.event.KeyAdapter;
52    import java.awt.event.KeyEvent;
53    import java.awt.event.MouseAdapter;
54    import java.awt.event.MouseEvent;
55    import java.awt.event.MouseListener;
56    import java.io.File;
57    import java.net.URL;
58    import java.util.ArrayList;
59    import java.util.LinkedHashMap;
60    import java.util.List;
61    import java.util.Map;
62   
63    import javax.swing.ButtonGroup;
64    import javax.swing.JButton;
65    import javax.swing.JCheckBox;
66    import javax.swing.JComboBox;
67    import javax.swing.JComponent;
68    import javax.swing.JLabel;
69    import javax.swing.JMenuItem;
70    import javax.swing.JPanel;
71    import javax.swing.JPopupMenu;
72    import javax.swing.JRadioButton;
73    import javax.swing.JScrollPane;
74    import javax.swing.JSlider;
75    import javax.swing.JTextArea;
76    import javax.swing.JTextField;
77    import javax.swing.border.TitledBorder;
78    import javax.swing.event.ChangeEvent;
79    import javax.swing.event.ChangeListener;
80   
81    import net.miginfocom.swing.MigLayout;
82   
83    /**
84    * GUI generator/manager for options and parameters. Originally abstracted from
85    * the WsJobParameters dialog box.
86    *
87    * @author jprocter
88    *
89    */
 
90    public class OptsAndParamsPage
91    {
92    public static final int PARAM_WIDTH = 340;
93   
94    public static final int PARAM_HEIGHT = 150;
95   
96    public static final int PARAM_CLOSEDHEIGHT = 80;
97   
98    URL linkImageURL = getClass().getResource("/images/link.gif");
99   
100    Map<String, OptionBox> optSet = new LinkedHashMap<>();
101   
102    Map<String, ParamBox> paramSet = new LinkedHashMap<>();
103   
104    /*
105    * compact or verbose style parameters
106    */
107    boolean compact = false;
108   
109    OptsParametersContainerI poparent;
110   
111    /**
112    * A class that models a panel rendering a single option (checkbox or choice
113    * list)
114    */
 
115    public class OptionBox extends JPanel
116    implements MouseListener, ActionListener
117    {
118    JCheckBox enabled;
119   
120    final URL finfo;
121   
122    boolean hasLink = false;
123   
124    boolean initEnabled = false;
125   
126    String initVal = null;
127   
128    OptionI option;
129   
130    JComboBox<Object> val;
131   
132    /**
133    * Constructs and adds labels and controls to the panel for one Option
134    *
135    * @param opt
136    */
137   
 
138  0 toggle public OptionBox(OptionI opt)
139    {
140  0 option = opt;
141  0 setLayout(new FlowLayout(FlowLayout.LEFT));
142  0 enabled = new JCheckBox(opt.getLabel());
143  0 enabled.setSelected(opt.isRequired());
144   
145    /*
146    * If option is required, show a label, if optional a checkbox
147    * (but not for Jabaws pending JWS-126 resolution)
148    */
149  0 if (opt.isRequired() && !(opt instanceof JabaOption))
150    {
151  0 finfo = null;
152  0 add(new JLabel(opt.getLabel()));
153    }
154    else
155    {
156  0 finfo = option.getFurtherDetails();
157  0 configureCheckbox(opt);
158  0 add(enabled);
159    }
160   
161    /*
162    * construct the choice box with possible values,
163    * or their display names if provided
164    */
165  0 val = buildComboBox(opt);
166  0 val.setSelectedItem(opt.getValue());
167   
168    /*
169    * only show the choicebox if there is more than one option,
170    * or the option is mandatory
171    */
172  0 if (opt.getPossibleValues().size() > 1 || opt.isRequired())
173    {
174  0 val.addActionListener(this);
175  0 add(val);
176    }
177   
178  0 setInitialValue();
179    }
180   
181    /**
182    * Configures the checkbox that controls whether or not the option is
183    * selected
184    *
185    * @param opt
186    */
 
187  0 toggle protected void configureCheckbox(OptionI opt)
188    {
189  0 enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
190  0 enabled.addActionListener(this);
191  0 final String desc = opt.getDescription();
192  0 if (finfo != null)
193    {
194  0 hasLink = true;
195   
196  0 String description = desc;
197  0 if (desc == null || desc.trim().isEmpty())
198    {
199  0 description = MessageManager
200    .getString("label.opt_and_params_further_details");
201    }
202  0 description = description + "<br><img src=\"" + linkImageURL
203    + "\"/>";
204  0 String text = JvSwingUtils.wrapTooltip(true, description);
205  0 enabled.setToolTipText(text);
206  0 enabled.addMouseListener(this); // for popup menu to show link
207    }
208    else
209    {
210  0 if (desc != null && desc.trim().length() > 0)
211    {
212  0 enabled.setToolTipText(JvSwingUtils.wrapTooltip(true, desc));
213    }
214    }
215    }
216   
 
217  0 toggle @Override
218    public void actionPerformed(ActionEvent e)
219    {
220  0 if (e.getSource() != enabled)
221    {
222  0 enabled.setSelected(true);
223    }
224  0 checkIfModified();
225    }
226   
 
227  0 toggle private void checkIfModified()
228    {
229  0 boolean notmod = (initEnabled == enabled.isSelected());
230  0 if (enabled.isSelected())
231    {
232  0 if (initVal != null)
233    {
234  0 notmod &= initVal.equals(val.getSelectedItem());
235    }
236    else
237    {
238    // compare against default service setting
239  0 notmod &= option.getValue() == null
240    || option.getValue().equals(val.getSelectedItem());
241    }
242    }
243    else
244    {
245  0 notmod &= (initVal != null) ? initVal.equals(val.getSelectedItem())
246    : val.getSelectedItem() != initVal;
247    }
248  0 poparent.argSetModified(this, !notmod);
249    }
250   
251    /**
252    * Answers null if the option is not selected, else a new Option holding the
253    * selected value
254    *
255    * @return
256    */
 
257  0 toggle public ArgumentI getSelectedOption()
258    {
259  0 if (!enabled.isSelected())
260    {
261  0 return null;
262    }
263  0 String value = getSelectedValue(option, val.getSelectedIndex());
264  0 OptionI opt = option.copy();
265  0 opt.setValue(value);
266  0 return opt;
267    }
268   
 
269  0 toggle @Override
270    public void mouseClicked(MouseEvent e)
271    {
272  0 if (e.isPopupTrigger()) // for Windows
273    {
274  0 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
275    }
276    }
277   
 
278  0 toggle @Override
279    public void mouseEntered(MouseEvent e)
280    {
281   
282    }
283   
 
284  0 toggle @Override
285    public void mouseExited(MouseEvent e)
286    {
287   
288    }
289   
 
290  0 toggle @Override
291    public void mousePressed(MouseEvent e)
292    {
293  0 if (e.isPopupTrigger()) // Mac
294    {
295  0 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
296    }
297    }
298   
 
299  0 toggle @Override
300    public void mouseReleased(MouseEvent e)
301    {
302    }
303   
 
304  0 toggle public void resetToDefault(boolean setDefaultParams)
305    {
306  0 enabled.setSelected(false);
307  0 if (option.isRequired()
308    || (setDefaultParams && option.getValue() != null))
309    {
310    // Apply default value
311  0 selectOption(option, option.getValue());
312    }
313    }
314   
 
315  0 toggle public void setInitialValue()
316    {
317  0 initEnabled = enabled.isSelected();
318  0 if (option.getPossibleValues() != null
319    && option.getPossibleValues().size() > 1)
320    {
321  0 initVal = (String) val.getSelectedItem();
322    }
323    else
324    {
325  0 initVal = (initEnabled) ? (String) val.getSelectedItem() : null;
326    }
327    }
328   
329    /**
330    * toString representation for identification in the debugger only
331    */
 
332  0 toggle @Override
333    public String toString()
334    {
335  0 return option == null ? super.toString() : option.toString();
336    }
337    }
338   
339    /**
340    * A class that models a panel rendering a single parameter
341    */
 
342    public class ParamBox extends JPanel
343    implements ChangeListener, ActionListener, MouseListener
344    {
345    /*
346    * parameter values (or their logs) are multiplied by this
347    * scaling factor to ensure an integer range for the slider
348    */
349    private int sliderScaleFactor = 1;
350   
351    boolean isLogarithmicParameter;
352   
353    boolean isChoiceParameter;
354   
355    boolean isIntegerParameter;
356   
357    boolean isStringParameter;
358   
359    boolean adjusting;
360   
361    /*
362    * drop-down list of choice options (if applicable)
363    */
364    JComboBox<Object> choicebox;
365   
366    /*
367    * radio buttons as an alternative to combo box
368    */
369    ButtonGroup buttonGroup;
370   
371    JPanel controlsPanel = new JPanel();
372   
373    boolean descriptionIsVisible = false;
374   
375    JScrollPane descPanel = new JScrollPane();
376   
377    final URL finfo;
378   
379    Object lastVal;
380   
381    ParameterI parameter;
382   
383    final OptsParametersContainerI pmdialogbox;
384   
385    JPanel settingPanel = new JPanel();
386   
387    JSlider slider;
388   
389    JTextArea descriptionText = new JTextArea();
390   
391    ValueConstrainI validator;
392   
393    JTextField valueField;
394   
395    private String descTooltip;
396   
 
397  0 toggle public ParamBox(final OptsParametersContainerI paramContainer,
398    ParameterI parm)
399    {
400  0 pmdialogbox = paramContainer;
401  0 finfo = parm.getFurtherDetails();
402  0 validator = parm.getValidValue();
403  0 parameter = parm;
404  0 isLogarithmicParameter = parm instanceof LogarithmicParameter;
405  0 if (validator != null)
406    {
407  0 ValueType type = validator.getType();
408  0 isIntegerParameter = type == ValueType.Integer;
409  0 isStringParameter = type == ValueType.String
410    || type == ValueType.File;
411   
412    /*
413    * ensure slider has an integer range corresponding to
414    * the min-max range of the parameter
415    */
416  0 if (validator.getMin() != null && validator.getMax() != null
417    // && !isIntegerParameter
418    && !isStringParameter)
419    {
420  0 double min = validator.getMin().doubleValue();
421  0 double max = validator.getMax().doubleValue();
422  0 if (isLogarithmicParameter)
423    {
424  0 min = Math.log(min);
425  0 max = Math.log(max);
426    }
427  0 sliderScaleFactor = (int) (1000000 / (max - min));
428    // todo scaleMin, scaleMax could also be final fields
429    }
430    }
431   
432  0 List<String> possibleValues = parameter.getPossibleValues();
433  0 isChoiceParameter = possibleValues != null
434    && !possibleValues.isEmpty();
435   
436  0 if (compact)
437    {
438  0 addCompactParameter(parm);
439    }
440    else
441    {
442  0 addExpandableParam(parm);
443   
444    }
445    }
446   
447    /**
448    * Adds a 'compact' format parameter, with any help text shown as a tooltip
449    *
450    * @param parm
451    */
 
452  0 toggle private void addCompactParameter(ParameterI parm)
453    {
454  0 setLayout(new MigLayout("", "[][grow]"));
455   
456  0 String ttipText = null;
457   
458  0 controlsPanel.setLayout(new BorderLayout());
459   
460  0 if (parm.getDescription() != null
461    && parm.getDescription().trim().length() > 0)
462    {
463  0 ttipText = (JvSwingUtils.wrapTooltip(true,
464  0 parm.getDescription() + (finfo != null ? "<br><img src=\""
465    + linkImageURL + "\"/>"
466    + MessageManager.getString(
467    "label.opt_and_params_further_details")
468    : "")));
469    }
470   
471  0 JvSwingUtils.addtoLayout(this, ttipText, new JLabel(parm.getName()),
472    controlsPanel, "");
473  0 updateControls(parm);
474  0 validate();
475    }
476   
477    /**
478    * Adds an 'expanded' format parameter, with any help shown in a panel that
479    * may be shown or hidden
480    *
481    * @param parm
482    */
 
483  0 toggle private void addExpandableParam(ParameterI parm)
484    {
485  0 setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT));
486  0 setBorder(new TitledBorder(parm.getName()));
487  0 setLayout(null);
488  0 descriptionText.setFont(new Font("Verdana", Font.PLAIN, 11));
489  0 descriptionText.setBackground(getBackground());
490   
491  0 descriptionText.setEditable(false);
492  0 descPanel.getViewport().setView(descriptionText);
493   
494  0 descPanel.setVisible(false);
495   
496  0 JPanel firstrow = new JPanel();
497  0 firstrow.setLayout(null);
498  0 controlsPanel.setLayout(new BorderLayout());
499  0 controlsPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
500    PARAM_CLOSEDHEIGHT - 50));
501  0 firstrow.add(controlsPanel);
502  0 firstrow.setBounds(new Rectangle(10, 20, PARAM_WIDTH - 30,
503    PARAM_CLOSEDHEIGHT - 30));
504   
505   
506  0 if (parm.getDescription() != null
507    && parm.getDescription().trim().length() > 0)
508    {
509  0 addExpandableHelp(firstrow, parm);
510    }
511  0 add(firstrow);
512  0 validator = parm.getValidValue();
513  0 parameter = parm;
514  0 if (validator != null)
515    {
516  0 isIntegerParameter = validator.getType() == ValueType.Integer;
517    }
518    else
519    {
520  0 if (parameter.getPossibleValues() != null)
521    {
522  0 isChoiceParameter = true;
523    }
524    }
525  0 updateControls(parm);
526  0 descPanel.setBounds(new Rectangle(10, PARAM_CLOSEDHEIGHT,
527    PARAM_WIDTH - 20, PARAM_HEIGHT - PARAM_CLOSEDHEIGHT - 5));
528  0 add(descPanel);
529  0 validate();
530    }
531   
532    /**
533    * Adds a button which can be clicked to show or hide help text
534    *
535    * @param container
536    * @param param
537    */
 
538  0 toggle protected void addExpandableHelp(JPanel container, ParameterI param)
539    {
540  0 JButton showDescBtn = new JButton("+");
541  0 showDescBtn.setFont(new Font("Verdana", Font.PLAIN, 8));
542  0 if (finfo != null)
543    {
544  0 descTooltip = JvSwingUtils.wrapTooltip(true,
545    MessageManager.formatMessage(
546    "label.opt_and_params_show_brief_desc_image_link",
547    new String[]
548    { linkImageURL.toExternalForm() }));
549  0 showDescBtn.addMouseListener(this);
550    }
551    else
552    {
553  0 descTooltip = JvSwingUtils.wrapTooltip(true, MessageManager
554    .getString("label.opt_and_params_show_brief_desc"));
555    }
556  0 showDescBtn.setToolTipText(descTooltip);
557  0 showDescBtn.addActionListener(new ActionListener()
558    {
 
559  0 toggle @Override
560    public void actionPerformed(ActionEvent e)
561    {
562  0 descriptionIsVisible = !descriptionIsVisible;
563  0 showDescBtn.setText(descriptionIsVisible ? "-" : "+");
564  0 showDescBtn.setToolTipText(
565  0 descriptionIsVisible ? null : descTooltip);
566  0 descPanel.setVisible(descriptionIsVisible);
567  0 descPanel.getVerticalScrollBar().setValue(0);
568  0 ParamBox.this.setPreferredSize(new Dimension(PARAM_WIDTH,
569  0 (descriptionIsVisible) ? PARAM_HEIGHT
570    : PARAM_CLOSEDHEIGHT));
571  0 ParamBox.this.validate();
572  0 pmdialogbox.refreshParamLayout();
573    }
574    });
575  0 descriptionText.setWrapStyleWord(true);
576  0 descriptionText.setLineWrap(true);
577  0 descriptionText.setColumns(32);
578  0 descriptionText.setText(param.getDescription());
579  0 showDescBtn.setBounds(new Rectangle(10, 10, 16, 16));
580  0 container.add(showDescBtn);
581    }
 
582  0 toggle @Override
583    public void actionPerformed(ActionEvent e)
584    {
585  0 if (adjusting)
586    {
587  0 return;
588    }
589  0 checkIfModified();
590    }
591   
592    /**
593    * Checks whether the value of this parameter has been changed and notifies
594    * the parent page accordingly
595    */
 
596  0 toggle private void checkIfModified()
597    {
598  0 Object newValue = updateSliderFromValueField();
599  0 boolean modified = true;
600  0 if (newValue.getClass() == lastVal.getClass())
601    {
602  0 modified = !newValue.equals(lastVal);
603    }
604  0 pmdialogbox.argSetModified(this, modified);
605    }
606   
607   
 
608  0 toggle @Override
609    public int getBaseline(int width, int height)
610    {
611  0 return 0;
612    }
613   
614    // from
615    // http://stackoverflow.com/questions/2743177/top-alignment-for-flowlayout
616    // helpful hint of using the Java 1.6 alignBaseLine property of FlowLayout
 
617  0 toggle @Override
618    public Component.BaselineResizeBehavior getBaselineResizeBehavior()
619    {
620  0 return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
621    }
622   
623    /**
624    * Answers an argument holding the value entered or selected in the dialog
625    *
626    * @return
627    */
 
628  0 toggle public ArgumentI getParameter()
629    {
630  0 ParameterI prm = parameter.copy();
631  0 String value = null;
632  0 if (parameter instanceof RadioChoiceParameter)
633    {
634  0 value = buttonGroup.getSelection().getActionCommand();
635    }
636  0 else if (isChoiceParameter)
637    {
638  0 value = getSelectedValue(this.parameter,
639    choicebox.getSelectedIndex());
640    }
641    else
642    {
643  0 value = valueField.getText();
644    }
645  0 prm.setValue(value);
646  0 return prm;
647    }
648   
 
649  0 toggle public void init()
650    {
651    // reset the widget's initial value.
652  0 lastVal = null;
653    }
654   
 
655  0 toggle @Override
656    public void mouseClicked(MouseEvent e)
657    {
658  0 if (e.isPopupTrigger()) // for Windows
659    {
660  0 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
661    }
662    }
663   
 
664  0 toggle @Override
665    public void mouseEntered(MouseEvent e)
666    {
667   
668    }
669   
 
670  0 toggle @Override
671    public void mouseExited(MouseEvent e)
672    {
673   
674    }
675   
 
676  0 toggle @Override
677    public void mousePressed(MouseEvent e)
678    {
679  0 if (e.isPopupTrigger()) // for Mac
680    {
681  0 showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
682    }
683    }
684   
 
685  0 toggle @Override
686    public void mouseReleased(MouseEvent e)
687    {
688   
689    }
690   
 
691  0 toggle @Override
692    public void stateChanged(ChangeEvent e)
693    {
694  0 if (adjusting)
695    {
696  0 return;
697    }
698  0 try
699    {
700  0 adjusting = true;
701  0 if (!isLogarithmicParameter)
702    {
703    /*
704    * set (int or float formatted) text field value
705    */
706  0 valueField.setText(isIntegerParameter
707    ? String.valueOf(slider.getValue())
708    : formatDouble(
709    slider.getValue() / (float) sliderScaleFactor));
710    }
711    else
712    {
713  0 double value = Math.pow(Math.E,
714    slider.getValue() / (double) sliderScaleFactor);
715  0 valueField.setText(formatDouble(value));
716    }
717  0 checkIfModified();
718    } finally
719    {
720  0 adjusting = false;
721    }
722    }
723   
724    /**
725    * Answers the value formatted as a string to 3 decimal places - in
726    * scientific notation if the value is less than 0.001
727    *
728    * @param value
729    * @return
730    */
 
731  0 toggle String formatDouble(double value)
732    {
733  0 String format = value < 0.001 ? "%3.1E" : "%3.3f";
734  0 return String.format(format, value);
735    }
736   
737    /**
738    * Formats a number as integer or float (3dp) or scientific notation (1dp)
739    *
740    * @param n
741    * @return
742    */
 
743  0 toggle String formatNumber(Number n)
744    {
745  0 return n instanceof Integer ? String.valueOf(n.intValue())
746    : formatDouble(n.doubleValue());
747    }
748   
 
749  0 toggle void updateControls(ParameterI parm)
750    {
751  0 adjusting = true;
752  0 boolean init = (choicebox == null && valueField == null
753    && buttonGroup == null);
754  0 if (init)
755    {
756  0 if (parm instanceof RadioChoiceParameter)
757    {
758  0 buttonGroup = addRadioButtons(parameter, controlsPanel);
759    }
760  0 else if (isChoiceParameter)
761    {
762  0 choicebox = buildComboBox(parm);
763  0 choicebox.addActionListener(this);
764  0 controlsPanel.add(choicebox, BorderLayout.CENTER);
765    }
766    else
767    {
768  0 slider = new JSlider();
769  0 slider.addChangeListener(this);
770  0 int cols = parm instanceof StringParameter ? 20 : 0;
771  0 valueField = new JTextField(cols);
772  0 valueField.addActionListener(this);
773  0 valueField.addKeyListener(new KeyAdapter()
774    {
775   
776   
 
777  0 toggle @Override
778    public void keyReleased(KeyEvent e)
779    {
780  0 int keyCode = e.getKeyCode();
781  0 if (e.isActionKey() && keyCode != KeyEvent.VK_LEFT
782    && keyCode != KeyEvent.VK_RIGHT)
783    {
784  0 if (valueField.getText().trim().length() > 0)
785    {
786  0 actionPerformed(null);
787    }
788    }
789    }
790   
791    });
792  0 valueField.addFocusListener(new FocusAdapter() {
793   
 
794  0 toggle @Override
795    public void focusLost(FocusEvent e)
796    {
797  0 actionPerformed(null);
798    }
799   
800    });
801  0 valueField.setPreferredSize(new Dimension(65, 25));
802  0 if (parm instanceof FileParameter)
803    {
804  0 valueField.setToolTipText(MessageManager
805    .getString("label.double_click_to_browse"));
806  0 valueField.addMouseListener(new MouseAdapter()
807    {
 
808  0 toggle @Override
809    public void mouseClicked(MouseEvent e)
810    {
811  0 if (e.getClickCount() == 2)
812    {
813  0 String dir = Cache.getProperty("LAST_DIRECTORY");
814  0 JalviewFileChooser chooser = new JalviewFileChooser(dir);
815  0 chooser.setFileView(new JalviewFileView());
816  0 chooser.setDialogTitle(
817    MessageManager.getString("action.select_ddbb"));
818   
819  0 int val = chooser.showOpenDialog(ParamBox.this);
820  0 if (val == JalviewFileChooser.APPROVE_OPTION)
821    {
822  0 File choice = chooser.getSelectedFile();
823  0 String path = choice.getPath();
824  0 valueField.setText(path);
825  0 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
826  0 FileLoader.updateRecentlyOpened(path,
827    DataSourceType.FILE);
828    }
829    }
830    }
831    });
832    }
833   
834  0 controlsPanel.add(slider, BorderLayout.WEST);
835  0 controlsPanel.add(valueField, BorderLayout.EAST);
836    }
837    }
838   
839  0 String value = parm.getValue();
840  0 if (value != null)
841    {
842  0 if (isChoiceParameter)
843    {
844  0 if (!(parm instanceof RadioChoiceParameter))
845    {
846  0 choicebox.setSelectedItem(value);
847    }
848    }
849    else
850    {
851  0 valueField.setText(value);
852    }
853    }
854  0 lastVal = updateSliderFromValueField();
855  0 adjusting = false;
856    }
857   
858    /**
859    * Adds a panel to comp, containing a label and radio buttons for the choice
860    * of values of the given option. Returns a ButtonGroup whose members are
861    * the added radio buttons.
862    *
863    * @param option
864    * @param comp
865    *
866    * @return
867    */
 
868  0 toggle protected ButtonGroup addRadioButtons(OptionI option, Container comp)
869    {
870  0 ButtonGroup bg = new ButtonGroup();
871  0 JPanel radioPanel = new JPanel();
872  0 radioPanel.add(new JLabel(option.getDescription()));
873   
874  0 String value = option.getValue();
875   
876  0 for (String opt : option.getPossibleValues())
877    {
878  0 JRadioButton btn = new JRadioButton(opt);
879  0 btn.setActionCommand(opt);
880  0 boolean selected = opt.equals(value);
881  0 btn.setSelected(selected);
882  0 btn.addActionListener(this);
883  0 bg.add(btn);
884  0 radioPanel.add(btn);
885    }
886  0 comp.add(radioPanel);
887   
888  0 return bg;
889    }
890   
891    /**
892    * Action depends on the type of the input parameter:
893    * <ul>
894    * <li>if a text input, returns the trimmed value</li>
895    * <li>if a choice list or radio button, returns the selected value</li>
896    * <li>if a value slider and input field, sets the value of the slider from
897    * the value in the text field, limiting it to any defined min-max
898    * range.</li>
899    * </ul>
900    * Answers the (possibly modified) input value, as a String, Integer, Float
901    * or Double.
902    *
903    * @return
904    */
 
905  0 toggle Object updateSliderFromValueField()
906    {
907  0 if (validator == null || isStringParameter)
908    {
909  0 if (isChoiceParameter)
910    {
911  0 if (parameter instanceof RadioChoiceParameter)
912    {
913  0 return buttonGroup.getSelection().getActionCommand();
914    }
915    else
916    {
917  0 return getSelectedValue(this.parameter,
918    choicebox.getSelectedIndex());
919    }
920    }
921  0 slider.setVisible(false);
922  0 return valueField.getText().trim();
923    }
924   
925  0 if (validator.getMin() == null || validator.getMax() == null)
926    {
927  0 slider.setVisible(false);
928    }
929   
930  0 valueField.setText(valueField.getText().trim());
931   
932    /*
933    * ensure not outside min-max range
934    * TODO: provide some visual indicator if limit reached
935    */
936  0 try
937    {
938  0 valueField.setBackground(Color.WHITE);
939  0 double d = Double.parseDouble(valueField.getText());
940  0 if (validator.getMin() != null
941    && validator.getMin().doubleValue() > d)
942    {
943  0 valueField.setText(formatNumber(validator.getMin()));
944    }
945  0 if (validator.getMax() != null
946    && validator.getMax().doubleValue() < d)
947    {
948  0 valueField.setText(formatNumber(validator.getMax()));
949    }
950    } catch (NumberFormatException e)
951    {
952  0 valueField.setBackground(Color.yellow);
953  0 return Float.NaN;
954    }
955  0 if (isIntegerParameter)
956    {
957  0 int iVal = 0;
958  0 try
959    {
960  0 iVal = Integer.valueOf(valueField.getText());
961    } catch (Exception e)
962    {
963  0 valueField.setBackground(Color.yellow);
964  0 return Integer.valueOf(0);
965    }
966   
967  0 if (validator.getMin() != null && validator.getMax() != null)
968    {
969  0 slider.getModel().setRangeProperties(iVal, 1,
970    validator.getMin().intValue(),
971    validator.getMax().intValue() + 1, true);
972    }
973    else
974    {
975  0 slider.setVisible(false);
976    }
977  0 return Integer.valueOf(iVal);
978    }
979  0 if (isLogarithmicParameter)
980    {
981  0 double dVal = 0d;
982  0 try
983    {
984  0 double eValue = Double.valueOf(valueField.getText());
985  0 dVal = Math.log(eValue);
986    } catch (Exception e)
987    {
988    // shouldn't be possible here
989  0 valueField.setBackground(Color.yellow);
990  0 return Double.NaN;
991    }
992  0 if (validator.getMin() != null && validator.getMax() != null)
993    {
994  0 double scaleMin = Math.log(validator.getMin().doubleValue())
995    * sliderScaleFactor;
996  0 double scaleMax = Math.log(validator.getMax().doubleValue())
997    * sliderScaleFactor;
998  0 slider.getModel().setRangeProperties(
999    (int) (sliderScaleFactor * dVal), 1,
1000    (int) scaleMin, 1 + (int) scaleMax, true);
1001    }
1002    else
1003    {
1004  0 slider.setVisible(false);
1005    }
1006  0 return Double.valueOf(dVal);
1007    }
1008  0 float fVal = 0f;
1009  0 try
1010    {
1011  0 fVal = Float.valueOf(valueField.getText());
1012    } catch (Exception e)
1013    {
1014  0 return Float.valueOf(0f); // shouldn't happen
1015    }
1016  0 if (validator.getMin() != null && validator.getMax() != null)
1017    {
1018  0 float scaleMin = validator.getMin().floatValue()
1019    * sliderScaleFactor;
1020  0 float scaleMax = validator.getMax().floatValue()
1021    * sliderScaleFactor;
1022  0 slider.getModel().setRangeProperties(
1023    (int) (fVal * sliderScaleFactor), 1, (int) scaleMin,
1024    1 + (int) scaleMax, true);
1025    }
1026    else
1027    {
1028  0 slider.setVisible(false);
1029    }
1030  0 return Float.valueOf(fVal);
1031    }
1032    }
1033   
1034    /**
1035    * Constructor with the option to show 'compact' format (parameter description
1036    * as tooltip) or 'expanded' format (parameter description in a textbox which
1037    * may be opened or closed). Use compact for simple description text, expanded
1038    * for more wordy or formatted text.
1039    *
1040    * @param paramContainer
1041    */
1042   
 
1043  0 toggle public OptsAndParamsPage(OptsParametersContainerI paramContainer,
1044    boolean compact)
1045    {
1046  0 poparent = paramContainer;
1047  0 this.compact = compact;
1048    }
1049   
 
1050  0 toggle public static void showUrlPopUp(JComponent invoker, final String finfo,
1051    int x, int y)
1052    {
1053   
1054  0 JPopupMenu mnu = new JPopupMenu();
1055  0 JMenuItem mitem = new JMenuItem(
1056    MessageManager.formatMessage("label.view_params", new String[]
1057    { finfo }));
1058  0 mitem.addActionListener(new ActionListener()
1059    {
1060   
 
1061  0 toggle @Override
1062    public void actionPerformed(ActionEvent e)
1063    {
1064  0 Desktop.showUrl(finfo);
1065   
1066    }
1067    });
1068  0 mnu.add(mitem);
1069  0 mnu.show(invoker, x, y);
1070    }
1071   
1072   
 
1073  0 toggle public Map<String, OptionBox> getOptSet()
1074    {
1075  0 return optSet;
1076    }
1077   
 
1078  0 toggle public void setOptSet(Map<String, OptionBox> optSet)
1079    {
1080  0 this.optSet = optSet;
1081    }
1082   
 
1083  0 toggle public Map<String, ParamBox> getParamSet()
1084    {
1085  0 return paramSet;
1086    }
1087   
 
1088  0 toggle public void setParamSet(Map<String, ParamBox> paramSet)
1089    {
1090  0 this.paramSet = paramSet;
1091    }
1092   
1093   
 
1094  0 toggle OptionBox addOption(OptionI opt)
1095    {
1096  0 OptionBox cb = optSet.get(opt.getName());
1097  0 if (cb == null)
1098    {
1099  0 cb = new OptionBox(opt);
1100  0 optSet.put(opt.getName(), cb);
1101    // jobOptions.add(cb, FlowLayout.LEFT);
1102    }
1103  0 return cb;
1104    }
1105   
 
1106  0 toggle ParamBox addParameter(ParameterI arg)
1107    {
1108  0 ParamBox pb = paramSet.get(arg.getName());
1109  0 if (pb == null)
1110    {
1111  0 pb = new ParamBox(poparent, arg);
1112  0 paramSet.put(arg.getName(), pb);
1113    // paramList.add(pb);
1114    }
1115  0 pb.init();
1116    // take the defaults from the parameter
1117  0 pb.updateControls(arg);
1118  0 return pb;
1119    }
1120   
 
1121  0 toggle void selectOption(OptionI option, String string)
1122    {
1123  0 OptionBox cb = optSet.get(option.getName());
1124  0 if (cb == null)
1125    {
1126  0 cb = addOption(option);
1127    }
1128  0 cb.enabled.setSelected(string != null); // initial state for an option.
1129  0 if (string != null)
1130    {
1131  0 if (option.getPossibleValues().contains(string))
1132    {
1133  0 cb.val.setSelectedItem(string);
1134    }
1135    else
1136    {
1137  0 throw new Error(MessageManager.formatMessage(
1138    "error.invalid_value_for_option", new String[]
1139    { string, option.getName() }));
1140    }
1141   
1142    }
1143  0 if (option.isRequired() && !cb.enabled.isSelected())
1144    {
1145    // TODO: indicate paramset is not valid.. option needs to be selected!
1146    }
1147  0 cb.setInitialValue();
1148    }
1149   
 
1150  0 toggle void setParameter(ParameterI arg)
1151    {
1152  0 ParamBox pb = paramSet.get(arg.getName());
1153  0 if (pb == null)
1154    {
1155  0 addParameter(arg);
1156    }
1157    else
1158    {
1159  0 pb.updateControls(arg);
1160    }
1161   
1162    }
1163   
1164    /**
1165    * Answers a list of arguments representing all the options and arguments
1166    * selected on the dialog, holding their chosen or input values. Optional
1167    * parameters which were not selected are not included.
1168    *
1169    * @return
1170    */
 
1171  0 toggle public List<ArgumentI> getCurrentSettings()
1172    {
1173  0 List<ArgumentI> argSet = new ArrayList<>();
1174  0 for (OptionBox opts : getOptSet().values())
1175    {
1176  0 ArgumentI opt = opts.getSelectedOption();
1177  0 if (opt != null)
1178    {
1179  0 argSet.add(opt);
1180    }
1181    }
1182  0 for (ParamBox parambox : getParamSet().values())
1183    {
1184  0 ArgumentI parm = parambox.getParameter();
1185  0 if (parm != null)
1186    {
1187  0 argSet.add(parm);
1188    }
1189    }
1190   
1191  0 return argSet;
1192    }
1193   
1194    /**
1195    * A helper method that constructs and returns a CombBox for choice of the
1196    * possible option values. If display names are provided, then these are added
1197    * as options, otherwise the actual values are added.
1198    *
1199    * @param opt
1200    * @return
1201    */
 
1202  0 toggle protected static JComboBox<Object> buildComboBox(OptionI opt)
1203    {
1204  0 JComboBox<Object> cb = null;
1205  0 List<String> displayNames = opt.getDisplayNames();
1206  0 if (displayNames != null)
1207    {
1208  0 List<Object> displayNamesObjects = new ArrayList<>();
1209  0 displayNamesObjects.addAll(displayNames);
1210  0 cb = JvSwingUtils.buildComboWithTooltips(displayNamesObjects,
1211    opt.getPossibleValues());
1212    }
1213    else
1214    {
1215  0 cb = new JComboBox<>();
1216  0 for (String v : opt.getPossibleValues())
1217    {
1218  0 cb.addItem(v);
1219    }
1220    }
1221  0 return cb;
1222    }
1223   
1224    /**
1225    * Answers the value corresponding to the selected item in the choice combo
1226    * box. Note that this returns the underlying value even if a different
1227    * display name is used in the combo box.
1228    *
1229    * @return
1230    */
 
1231  0 toggle protected static String getSelectedValue(OptionI opt, int sel)
1232    {
1233  0 List<String> possibleValues = opt.getPossibleValues();
1234  0 String value = null;
1235  0 if (possibleValues != null && possibleValues.size() == 1)
1236    {
1237    // Hack to make sure the default value for an enabled option with only
1238    // one value is actually returned even if this.val is not displayed
1239  0 value = possibleValues.get(0);
1240    }
1241  0 else if (sel >= 0 && sel < possibleValues.size())
1242    {
1243  0 value = possibleValues.get(sel);
1244    }
1245  0 return value;
1246    }
1247    }