*/
package jalview.gui;
+import jalview.bin.Cache;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.util.MessageManager;
+import jalview.ws.jws2.dm.JabaOption;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.OptionI;
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.ValueConstrainI;
+import jalview.ws.params.ValueConstrainI.ValueType;
+import jalview.ws.params.simple.FileParameter;
+import jalview.ws.params.simple.LogarithmicParameter;
+import jalview.ws.params.simple.RadioChoiceParameter;
+import jalview.ws.params.simple.StringParameter;
import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
+import java.awt.FlowLayout;
import java.awt.Font;
-import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
+import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
+import java.io.File;
import java.net.URL;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
+import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import jalview.util.MessageManager;
-import jalview.ws.params.ArgumentI;
-import jalview.ws.params.OptionI;
-import jalview.ws.params.ParameterI;
-import jalview.ws.params.ValueConstrainI;
-import jalview.ws.params.ValueConstrainI.ValueType;
import net.miginfocom.swing.MigLayout;
/**
*/
public class OptsAndParamsPage
{
- /**
+ public static final int PARAM_WIDTH = 340;
+
+ public static final int PARAM_HEIGHT = 150;
+
+ public static final int PARAM_CLOSEDHEIGHT = 80;
+
+ URL linkImageURL = getClass().getResource("/images/link.gif");
+
+ Map<String, OptionBox> optSet = new LinkedHashMap<>();
+
+ Map<String, ParamBox> paramSet = new LinkedHashMap<>();
+
+ /*
* compact or verbose style parameters
*/
boolean compact = false;
+ OptsParametersContainerI poparent;
+
+ /**
+ * A class that models a panel rendering a single option (checkbox or choice
+ * list)
+ */
public class OptionBox extends JPanel
implements MouseListener, ActionListener
{
- JCheckBox enabled = new JCheckBox();
+ JCheckBox enabled;
final URL finfo;
OptionI option;
- JLabel optlabel = new JLabel();
+ JComboBox<Object> val;
- JComboBox<String> val = new JComboBox<>();
+ /**
+ * Constructs and adds labels and controls to the panel for one Option
+ *
+ * @param opt
+ */
public OptionBox(OptionI opt)
{
option = opt;
- setLayout(new BorderLayout());
- enabled.setSelected(opt.isRequired()); // TODO: lock required options
+ setLayout(new FlowLayout(FlowLayout.LEFT));
+ enabled = new JCheckBox(opt.getLabel());
+ enabled.setSelected(opt.isRequired());
+
+ /*
+ * If option is required, show a label, if optional a checkbox
+ * (but not for Jabaws pending JWS-126 resolution)
+ */
+ if (opt.isRequired() && !(opt instanceof JabaOption))
+ {
+ finfo = null;
+ add(new JLabel(opt.getLabel()));
+ }
+ else
+ {
+ finfo = option.getFurtherDetails();
+ configureCheckbox(opt);
+ add(enabled);
+ }
+
+ /*
+ * construct the choice box with possible values,
+ * or their display names if provided
+ */
+ val = buildComboBox(opt);
+ val.setSelectedItem(opt.getValue());
+
+ /*
+ * only show the choicebox if there is more than one option,
+ * or the option is mandatory
+ */
+ if (opt.getPossibleValues().size() > 1 || opt.isRequired())
+ {
+ val.addActionListener(this);
+ add(val);
+ }
+
+ setInitialValue();
+ }
+
+ /**
+ * Configures the checkbox that controls whether or not the option is
+ * selected
+ *
+ * @param opt
+ */
+ protected void configureCheckbox(OptionI opt)
+ {
enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
- enabled.setText("");
- enabled.setText(opt.getName());
enabled.addActionListener(this);
- finfo = option.getFurtherDetails();
- String desc = opt.getDescription();
+ final String desc = opt.getDescription();
if (finfo != null)
{
hasLink = true;
- enabled.setToolTipText(JvSwingUtils.wrapTooltip(true,
- ((desc == null || desc.trim().length() == 0)
- ? MessageManager.getString(
- "label.opt_and_params_further_details")
- : desc) + "<br><img src=\"" + linkImageURL
- + "\"/>"));
- enabled.addMouseListener(this);
+ String description = desc;
+ if (desc == null || desc.trim().isEmpty())
+ {
+ description = MessageManager
+ .getString("label.opt_and_params_further_details");
+ }
+ description = description + "<br><img src=\"" + linkImageURL
+ + "\"/>";
+ String text = JvSwingUtils.wrapTooltip(true, description);
+ enabled.setToolTipText(text);
+ enabled.addMouseListener(this); // for popup menu to show link
}
else
{
if (desc != null && desc.trim().length() > 0)
{
- enabled.setToolTipText(
- JvSwingUtils.wrapTooltip(true, opt.getDescription()));
+ enabled.setToolTipText(JvSwingUtils.wrapTooltip(true, desc));
}
}
- add(enabled, BorderLayout.NORTH);
- for (String str : opt.getPossibleValues())
- {
- val.addItem(str);
- }
- val.setSelectedItem(opt.getValue());
- if (opt.getPossibleValues().size() > 1)
- {
- setLayout(new GridLayout(1, 2));
- val.addActionListener(this);
- add(val, BorderLayout.SOUTH);
- }
- // TODO: add actionListeners for popup (to open further info),
- // and to update list of parameters if an option is enabled
- // that takes a value. JBPNote: is this TODO still valid ?
- setInitialValue();
}
@Override
poparent.argSetModified(this, !notmod);
}
- public OptionI getOptionIfEnabled()
+ /**
+ * Answers null if the option is not selected, else a new Option holding the
+ * selected value
+ *
+ * @return
+ */
+ public ArgumentI getSelectedOption()
{
if (!enabled.isSelected())
{
return null;
}
+ String value = getSelectedValue(option, val.getSelectedIndex());
OptionI opt = option.copy();
- if (opt.getPossibleValues() != null
- && opt.getPossibleValues().size() == 1)
- {
- // Hack to make sure the default value for an enabled option with only
- // one value is actually returned
- opt.setValue(opt.getPossibleValues().get(0));
- }
- if (val.getSelectedItem() != null)
- {
- opt.setValue((String) val.getSelectedItem());
- }
- else
- {
- if (option.getValue() != null)
- {
- opt.setValue(option.getValue());
- }
- }
+ opt.setValue(value);
return opt;
}
@Override
public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e)
{
- // TODO Auto-generated method stub
}
}
}
+ /**
+ * toString representation for identification in the debugger only
+ */
+ @Override
+ public String toString()
+ {
+ return option == null ? super.toString() : option.toString();
+ }
}
+ /**
+ * A class that models a panel rendering a single parameter
+ */
public class ParamBox extends JPanel
implements ChangeListener, ActionListener, MouseListener
{
- boolean adjusting = false;
+ /*
+ * parameter values (or their logs) are multiplied by this
+ * scaling factor to ensure an integer range for the slider
+ */
+ private int sliderScaleFactor = 1;
+
+ boolean isLogarithmicParameter;
+
+ boolean isChoiceParameter;
- boolean choice = false;
+ boolean isIntegerParameter;
- JComboBox<String> choicebox;
+ boolean isStringParameter;
- JPanel controlPanel = new JPanel();
+ boolean adjusting;
- boolean descisvisible = false;
+ /*
+ * drop-down list of choice options (if applicable)
+ */
+ JComboBox<Object> choicebox;
+
+ /*
+ * radio buttons as an alternative to combo box
+ */
+ ButtonGroup buttonGroup;
+
+ JPanel controlsPanel = new JPanel();
+
+ boolean descriptionIsVisible = false;
JScrollPane descPanel = new JScrollPane();
final URL finfo;
- boolean integ = false;
-
- String lastVal;
+ Object lastVal;
ParameterI parameter;
JPanel settingPanel = new JPanel();
- JButton showDesc = new JButton();
+ JSlider slider;
- Slider slider = null;
+ JTextArea descriptionText = new JTextArea();
- JTextArea string = new JTextArea();
+ ValueConstrainI validator;
- ValueConstrainI validator = null;
+ JTextField valueField;
- JTextField valueField = null;
+ private String descTooltip;
- public ParamBox(final OptsParametersContainerI pmlayout,
+ public ParamBox(final OptsParametersContainerI paramContainer,
ParameterI parm)
{
- pmdialogbox = pmlayout;
+ pmdialogbox = paramContainer;
finfo = parm.getFurtherDetails();
validator = parm.getValidValue();
parameter = parm;
+ isLogarithmicParameter = parm instanceof LogarithmicParameter;
if (validator != null)
{
- integ = validator.getType() == ValueType.Integer;
- }
- else
- {
- if (parameter.getPossibleValues() != null)
+ ValueType type = validator.getType();
+ isIntegerParameter = type == ValueType.Integer;
+ isStringParameter = type == ValueType.String
+ || type == ValueType.File;
+
+ /*
+ * ensure slider has an integer range corresponding to
+ * the min-max range of the parameter
+ */
+ if (validator.getMin() != null && validator.getMax() != null
+ // && !isIntegerParameter
+ && !isStringParameter)
{
- choice = true;
+ double min = validator.getMin().doubleValue();
+ double max = validator.getMax().doubleValue();
+ if (isLogarithmicParameter)
+ {
+ min = Math.log(min);
+ max = Math.log(max);
+ }
+ sliderScaleFactor = (int) (1000000 / (max - min));
+ // todo scaleMin, scaleMax could also be final fields
}
}
- if (!compact)
+ List<String> possibleValues = parameter.getPossibleValues();
+ isChoiceParameter = possibleValues != null
+ && !possibleValues.isEmpty();
+
+ if (compact)
{
- makeExpanderParam(parm);
+ addCompactParameter(parm);
}
else
{
- makeCompactParam(parm);
+ addExpandableParam(parm);
}
}
- private void makeCompactParam(ParameterI parm)
+ /**
+ * Adds a 'compact' format parameter, with any help text shown as a tooltip
+ *
+ * @param parm
+ */
+ private void addCompactParameter(ParameterI parm)
{
setLayout(new MigLayout("", "[][grow]"));
String ttipText = null;
- controlPanel.setLayout(new BorderLayout());
+ controlsPanel.setLayout(new BorderLayout());
if (parm.getDescription() != null
&& parm.getDescription().trim().length() > 0)
{
- // Only create description boxes if there actually is a description.
ttipText = (JvSwingUtils.wrapTooltip(true,
parm.getDescription() + (finfo != null ? "<br><img src=\""
+ linkImageURL + "\"/>"
: "")));
}
- JvSwingUtils.mgAddtoLayout(this, ttipText, new JLabel(parm.getName()),
- controlPanel, "");
+ JvSwingUtils.addtoLayout(this, ttipText, new JLabel(parm.getName()),
+ controlsPanel, "");
updateControls(parm);
validate();
}
- private void makeExpanderParam(final ParameterI parm)
+ /**
+ * Adds an 'expanded' format parameter, with any help shown in a panel that
+ * may be shown or hidden
+ *
+ * @param parm
+ */
+ private void addExpandableParam(ParameterI parm)
{
setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT));
setBorder(new TitledBorder(parm.getName()));
setLayout(null);
- showDesc.setFont(new Font("Verdana", Font.PLAIN, 6));
- showDesc.setText("+");
- string.setFont(new Font("Verdana", Font.PLAIN, 11));
- string.setBackground(getBackground());
+ descriptionText.setFont(new Font("Verdana", Font.PLAIN, 11));
+ descriptionText.setBackground(getBackground());
- string.setEditable(false);
- descPanel.getViewport().setView(string);
+ descriptionText.setEditable(false);
+ descPanel.getViewport().setView(descriptionText);
descPanel.setVisible(false);
JPanel firstrow = new JPanel();
firstrow.setLayout(null);
- controlPanel.setLayout(new BorderLayout());
- controlPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
+ controlsPanel.setLayout(new BorderLayout());
+ controlsPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
PARAM_CLOSEDHEIGHT - 50));
- firstrow.add(controlPanel);
+ firstrow.add(controlsPanel);
firstrow.setBounds(new Rectangle(10, 20, PARAM_WIDTH - 30,
PARAM_CLOSEDHEIGHT - 30));
- final ParamBox me = this;
if (parm.getDescription() != null
&& parm.getDescription().trim().length() > 0)
{
- // Only create description boxes if there actually is a description.
- if (finfo != null)
- {
- showDesc.setToolTipText(JvSwingUtils.wrapTooltip(true,
- MessageManager.formatMessage(
- "label.opt_and_params_show_brief_desc_image_link",
- new String[]
- { linkImageURL.toExternalForm() })));
- showDesc.addMouseListener(this);
- }
- else
- {
- showDesc.setToolTipText(
- JvSwingUtils.wrapTooltip(true, MessageManager.getString(
- "label.opt_and_params_show_brief_desc")));
- }
- showDesc.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- descisvisible = !descisvisible;
- descPanel.setVisible(descisvisible);
- descPanel.getVerticalScrollBar().setValue(0);
- me.setPreferredSize(new Dimension(PARAM_WIDTH,
- (descisvisible) ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT));
- me.validate();
- pmdialogbox.refreshParamLayout();
- }
- });
- string.setWrapStyleWord(true);
- string.setLineWrap(true);
- string.setColumns(32);
- string.setText(parm.getDescription());
- showDesc.setBounds(new Rectangle(10, 10, 16, 16));
- firstrow.add(showDesc);
+ addExpandableHelp(firstrow, parm);
}
add(firstrow);
validator = parm.getValidValue();
parameter = parm;
if (validator != null)
{
- integ = validator.getType() == ValueType.Integer;
+ isIntegerParameter = validator.getType() == ValueType.Integer;
}
else
{
if (parameter.getPossibleValues() != null)
{
- choice = true;
+ isChoiceParameter = true;
}
}
updateControls(parm);
}
/**
- * Action on input in text field
+ * Adds a button which can be clicked to show or hide help text
+ *
+ * @param container
+ * @param param
*/
+ protected void addExpandableHelp(JPanel container, ParameterI param)
+ {
+ JButton showDescBtn = new JButton("+");
+ showDescBtn.setFont(new Font("Verdana", Font.PLAIN, 8));
+ if (finfo != null)
+ {
+ descTooltip = JvSwingUtils.wrapTooltip(true,
+ MessageManager.formatMessage(
+ "label.opt_and_params_show_brief_desc_image_link",
+ new String[]
+ { linkImageURL.toExternalForm() }));
+ showDescBtn.addMouseListener(this);
+ }
+ else
+ {
+ descTooltip = JvSwingUtils.wrapTooltip(true, MessageManager
+ .getString("label.opt_and_params_show_brief_desc"));
+ }
+ showDescBtn.setToolTipText(descTooltip);
+ showDescBtn.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ descriptionIsVisible = !descriptionIsVisible;
+ showDescBtn.setText(descriptionIsVisible ? "-" : "+");
+ showDescBtn.setToolTipText(
+ descriptionIsVisible ? null : descTooltip);
+ descPanel.setVisible(descriptionIsVisible);
+ descPanel.getVerticalScrollBar().setValue(0);
+ ParamBox.this.setPreferredSize(new Dimension(PARAM_WIDTH,
+ (descriptionIsVisible) ? PARAM_HEIGHT
+ : PARAM_CLOSEDHEIGHT));
+ ParamBox.this.validate();
+ pmdialogbox.refreshParamLayout();
+ }
+ });
+ descriptionText.setWrapStyleWord(true);
+ descriptionText.setLineWrap(true);
+ descriptionText.setColumns(32);
+ descriptionText.setText(param.getDescription());
+ showDescBtn.setBounds(new Rectangle(10, 10, 16, 16));
+ container.add(showDescBtn);
+ }
@Override
public void actionPerformed(ActionEvent e)
{
{
return;
}
- if (!choice)
- {
- updateSliderFromValueField();
- }
checkIfModified();
}
+ /**
+ * Checks whether the value of this parameter has been changed and notifies
+ * the parent page accordingly
+ */
private void checkIfModified()
{
- Object cstate = getCurrentValue();
- boolean modified = !cstate.equals(lastVal);
+ Object newValue = updateSliderFromValueField();
+ boolean modified = true;
+ if (newValue.getClass() == lastVal.getClass())
+ {
+ modified = !newValue.equals(lastVal);
+ }
pmdialogbox.argSetModified(this, modified);
}
- /**
- * Answers the current value of the parameter, as text
- *
- * @return
- */
- private String getCurrentValue()
- {
- return choice ? (String) choicebox.getSelectedItem()
- : valueField.getText();
- }
@Override
public int getBaseline(int width, int height)
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
- public int getBoxHeight()
- {
- return (descisvisible ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT);
- }
-
- public ParameterI getParameter()
+ /**
+ * Answers an argument holding the value entered or selected in the dialog
+ *
+ * @return
+ */
+ public ArgumentI getParameter()
{
ParameterI prm = parameter.copy();
- if (choice)
+ String value = null;
+ if (parameter instanceof RadioChoiceParameter)
{
- prm.setValue((String) choicebox.getSelectedItem());
+ value = buttonGroup.getSelection().getActionCommand();
+ }
+ else if (isChoiceParameter)
+ {
+ value = getSelectedValue(this.parameter,
+ choicebox.getSelectedIndex());
}
else
{
- prm.setValue(valueField.getText());
+ value = valueField.getText();
}
+ prm.setValue(value);
return prm;
}
@Override
public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e)
{
- // TODO Auto-generated method stub
}
- /**
- * Action on change of slider value
- */
@Override
public void stateChanged(ChangeEvent e)
{
- if (!adjusting)
+ if (adjusting)
{
- float value = slider.getSliderValue();
- valueField.setText(integ ? Integer.toString((int) value)
- : Float.toString(value));
+ return;
+ }
+ try
+ {
+ adjusting = true;
+ if (!isLogarithmicParameter)
+ {
+ /*
+ * set (int or float formatted) text field value
+ */
+ valueField.setText(isIntegerParameter
+ ? String.valueOf(slider.getValue())
+ : formatDouble(
+ slider.getValue() / (float) sliderScaleFactor));
+ }
+ else
+ {
+ double value = Math.pow(Math.E,
+ slider.getValue() / (double) sliderScaleFactor);
+ valueField.setText(formatDouble(value));
+ }
checkIfModified();
+ } finally
+ {
+ adjusting = false;
}
}
- public void updateControls(ParameterI parm)
+ /**
+ * Answers the value formatted as a string to 3 decimal places - in
+ * scientific notation if the value is less than 0.001
+ *
+ * @param value
+ * @return
+ */
+ String formatDouble(double value)
+ {
+ String format = value < 0.001 ? "%3.1E" : "%3.3f";
+ return String.format(format, value);
+ }
+
+ /**
+ * Formats a number as integer or float (3dp) or scientific notation (1dp)
+ *
+ * @param n
+ * @return
+ */
+ String formatNumber(Number n)
+ {
+ return n instanceof Integer ? String.valueOf(n.intValue())
+ : formatDouble(n.doubleValue());
+ }
+
+ void updateControls(ParameterI parm)
{
adjusting = true;
- boolean init = (choicebox == null && valueField == null);
+ boolean init = (choicebox == null && valueField == null
+ && buttonGroup == null);
if (init)
{
- if (choice)
+ if (parm instanceof RadioChoiceParameter)
+ {
+ buttonGroup = addRadioButtons(parameter, controlsPanel);
+ }
+ else if (isChoiceParameter)
{
- choicebox = new JComboBox<>();
+ choicebox = buildComboBox(parm);
choicebox.addActionListener(this);
- controlPanel.add(choicebox, BorderLayout.CENTER);
+ controlsPanel.add(choicebox, BorderLayout.CENTER);
}
else
{
- valueField = new JTextField();
+ slider = new JSlider();
+ slider.addChangeListener(this);
+ int cols = parm instanceof StringParameter ? 20 : 0;
+ valueField = new JTextField(cols);
valueField.addActionListener(this);
- valueField.addKeyListener(new KeyListener()
+ valueField.addKeyListener(new KeyAdapter()
{
- @Override
- public void keyTyped(KeyEvent e)
- {
- }
@Override
public void keyReleased(KeyEvent e)
{
- if (e.isActionKey())
+ int keyCode = e.getKeyCode();
+ if (e.isActionKey() && keyCode != KeyEvent.VK_LEFT
+ && keyCode != KeyEvent.VK_RIGHT)
{
if (valueField.getText().trim().length() > 0)
{
}
}
- @Override
- public void keyPressed(KeyEvent e)
- {
- }
});
- valueField.addFocusListener(new FocusAdapter()
- {
+ valueField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e)
{
actionPerformed(null);
}
-
+
});
- valueField.setPreferredSize(new Dimension(60, 25));
- valueField.setText(parm.getValue());
- slider = makeSlider(parm.getValidValue());
- updateSliderFromValueField();
- slider.addChangeListener(this);
-
- controlPanel.add(slider, BorderLayout.WEST);
- controlPanel.add(valueField, BorderLayout.EAST);
+ valueField.setPreferredSize(new Dimension(65, 25));
+ if (parm instanceof FileParameter)
+ {
+ valueField.setToolTipText(MessageManager
+ .getString("label.double_click_to_browse"));
+ valueField.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+ String dir = Cache.getProperty("LAST_DIRECTORY");
+ JalviewFileChooser chooser = new JalviewFileChooser(dir);
+ chooser.setFileView(new JalviewFileView());
+ chooser.setDialogTitle(
+ MessageManager.getString("action.select_ddbb"));
+
+ int val = chooser.showOpenDialog(ParamBox.this);
+ if (val == JalviewFileChooser.APPROVE_OPTION)
+ {
+ File choice = chooser.getSelectedFile();
+ String path = choice.getPath();
+ valueField.setText(path);
+ Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+ FileLoader.updateRecentlyOpened(path,
+ DataSourceType.FILE);
+ }
+ }
+ }
+ });
+ }
+
+ controlsPanel.add(slider, BorderLayout.WEST);
+ controlsPanel.add(valueField, BorderLayout.EAST);
}
}
- if (parm != null)
+ String value = parm.getValue();
+ if (value != null)
{
- if (choice)
+ if (isChoiceParameter)
{
- if (init)
+ if (!(parm instanceof RadioChoiceParameter))
{
- List<String> vals = parm.getPossibleValues();
- for (String val : vals)
- {
- choicebox.addItem(val);
- }
- }
-
- if (parm.getValue() != null)
- {
- choicebox.setSelectedItem(parm.getValue());
+ choicebox.setSelectedItem(value);
}
}
else
{
- valueField.setText(parm.getValue());
+ valueField.setText(value);
}
}
- lastVal = getCurrentValue();
+ lastVal = updateSliderFromValueField();
adjusting = false;
}
- private Slider makeSlider(ValueConstrainI validValue)
+ /**
+ * Adds a panel to comp, containing a label and radio buttons for the choice
+ * of values of the given option. Returns a ButtonGroup whose members are
+ * the added radio buttons.
+ *
+ * @param option
+ * @param comp
+ *
+ * @return
+ */
+ protected ButtonGroup addRadioButtons(OptionI option, Container comp)
{
- if (validValue != null)
+ ButtonGroup bg = new ButtonGroup();
+ JPanel radioPanel = new JPanel();
+ radioPanel.add(new JLabel(option.getDescription()));
+
+ String value = option.getValue();
+
+ for (String opt : option.getPossibleValues())
{
- final Number minValue = validValue.getMin();
- final Number maxValue = validValue.getMax();
- if (minValue != null && maxValue != null)
- {
- return new Slider(minValue.floatValue(), maxValue.floatValue(),
- minValue.floatValue());
- }
+ JRadioButton btn = new JRadioButton(opt);
+ btn.setActionCommand(opt);
+ boolean selected = opt.equals(value);
+ btn.setSelected(selected);
+ btn.addActionListener(this);
+ bg.add(btn);
+ radioPanel.add(btn);
}
+ comp.add(radioPanel);
- /*
- * otherwise, a nominal slider which will not be visible
- */
- return new Slider(0, 100, 50);
+ return bg;
}
- public void updateSliderFromValueField()
+ /**
+ * Action depends on the type of the input parameter:
+ * <ul>
+ * <li>if a text input, returns the trimmed value</li>
+ * <li>if a choice list or radio button, returns the selected value</li>
+ * <li>if a value slider and input field, sets the value of the slider from
+ * the value in the text field, limiting it to any defined min-max
+ * range.</li>
+ * </ul>
+ * Answers the (possibly modified) input value, as a String, Integer, Float
+ * or Double.
+ *
+ * @return
+ */
+ Object updateSliderFromValueField()
{
- if (validator != null)
+ if (validator == null || isStringParameter)
{
- final Number minValue = validator.getMin();
- final Number maxValue = validator.getMax();
- if (integ)
+ if (isChoiceParameter)
{
- int iVal = 0;
- try
+ if (parameter instanceof RadioChoiceParameter)
{
- valueField.setText(valueField.getText().trim());
- iVal = Integer.valueOf(valueField.getText());
- if (minValue != null && minValue.intValue() > iVal)
- {
- iVal = minValue.intValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- }
- if (maxValue != null && maxValue.intValue() < iVal)
- {
- iVal = maxValue.intValue();
- }
- } catch (NumberFormatException e)
- {
- System.err.println(e.toString());
- }
- if (minValue != null || maxValue != null)
- {
- valueField.setText(String.valueOf(iVal));
- slider.setSliderValue(iVal);
+ return buttonGroup.getSelection().getActionCommand();
}
else
{
- slider.setVisible(false);
+ return getSelectedValue(this.parameter,
+ choicebox.getSelectedIndex());
}
}
+ slider.setVisible(false);
+ return valueField.getText().trim();
+ }
+
+ if (validator.getMin() == null || validator.getMax() == null)
+ {
+ slider.setVisible(false);
+ }
+
+ valueField.setText(valueField.getText().trim());
+
+ /*
+ * ensure not outside min-max range
+ * TODO: provide some visual indicator if limit reached
+ */
+ try
+ {
+ valueField.setBackground(Color.WHITE);
+ double d = Double.parseDouble(valueField.getText());
+ if (validator.getMin() != null
+ && validator.getMin().doubleValue() > d)
+ {
+ valueField.setText(formatNumber(validator.getMin()));
+ }
+ if (validator.getMax() != null
+ && validator.getMax().doubleValue() < d)
+ {
+ valueField.setText(formatNumber(validator.getMax()));
+ }
+ } catch (NumberFormatException e)
+ {
+ valueField.setBackground(Color.yellow);
+ return Float.NaN;
+ }
+ if (isIntegerParameter)
+ {
+ int iVal = 0;
+ try
+ {
+ iVal = Integer.valueOf(valueField.getText());
+ } catch (Exception e)
+ {
+ valueField.setBackground(Color.yellow);
+ return Integer.valueOf(0);
+ }
+
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ slider.getModel().setRangeProperties(iVal, 1,
+ validator.getMin().intValue(),
+ validator.getMax().intValue() + 1, true);
+ }
else
{
- float fVal = 0f;
- try
- {
- valueField.setText(valueField.getText().trim());
- fVal = Float.valueOf(valueField.getText());
- if (minValue != null && minValue.floatValue() > fVal)
- {
- fVal = minValue.floatValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- // update value field to reflect any bound checking we performed.
- valueField.setText("" + fVal);
- }
- if (maxValue != null && maxValue.floatValue() < fVal)
- {
- fVal = maxValue.floatValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- // update value field to reflect any bound checking we performed.
- valueField.setText("" + fVal);
- }
- } catch (NumberFormatException e)
- {
- System.err.println(e.toString());
- }
- if (minValue != null && maxValue != null)
- {
- slider.setSliderModel(minValue.floatValue(),
- maxValue.floatValue(), fVal);
- }
- else
- {
- slider.setVisible(false);
- }
+ slider.setVisible(false);
}
+ return Integer.valueOf(iVal);
}
- else
+ if (isLogarithmicParameter)
{
- if (!choice)
+ double dVal = 0d;
+ try
+ {
+ double eValue = Double.valueOf(valueField.getText());
+ dVal = Math.log(eValue);
+ } catch (Exception e)
+ {
+ // shouldn't be possible here
+ valueField.setBackground(Color.yellow);
+ return Double.NaN;
+ }
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ double scaleMin = Math.log(validator.getMin().doubleValue())
+ * sliderScaleFactor;
+ double scaleMax = Math.log(validator.getMax().doubleValue())
+ * sliderScaleFactor;
+ slider.getModel().setRangeProperties(
+ (int) (sliderScaleFactor * dVal), 1,
+ (int) scaleMin, 1 + (int) scaleMax, true);
+ }
+ else
{
slider.setVisible(false);
}
+ return Double.valueOf(dVal);
}
+ float fVal = 0f;
+ try
+ {
+ fVal = Float.valueOf(valueField.getText());
+ } catch (Exception e)
+ {
+ return Float.valueOf(0f); // shouldn't happen
+ }
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ float scaleMin = validator.getMin().floatValue()
+ * sliderScaleFactor;
+ float scaleMax = validator.getMax().floatValue()
+ * sliderScaleFactor;
+ slider.getModel().setRangeProperties(
+ (int) (fVal * sliderScaleFactor), 1, (int) scaleMin,
+ 1 + (int) scaleMax, true);
+ }
+ else
+ {
+ slider.setVisible(false);
+ }
+ return Float.valueOf(fVal);
}
}
- public static final int PARAM_WIDTH = 340;
-
- public static final int PARAM_HEIGHT = 150;
-
- public static final int PARAM_CLOSEDHEIGHT = 80;
-
- public OptsAndParamsPage(OptsParametersContainerI paramContainer)
- {
- this(paramContainer, false);
- }
+ /**
+ * Constructor with the option to show 'compact' format (parameter description
+ * as tooltip) or 'expanded' format (parameter description in a textbox which
+ * may be opened or closed). Use compact for simple description text, expanded
+ * for more wordy or formatted text.
+ *
+ * @param paramContainer
+ */
public OptsAndParamsPage(OptsParametersContainerI paramContainer,
boolean compact)
mnu.show(invoker, x, y);
}
- URL linkImageURL = getClass().getResource("/images/link.gif");
-
- Map<String, OptionBox> optSet = new java.util.LinkedHashMap<>();
-
- Map<String, ParamBox> paramSet = new java.util.LinkedHashMap<>();
public Map<String, OptionBox> getOptSet()
{
this.paramSet = paramSet;
}
- OptsParametersContainerI poparent;
OptionBox addOption(OptionI opt)
{
}
/**
- * recover options and parameters from GUI
+ * Answers a list of arguments representing all the options and arguments
+ * selected on the dialog, holding their chosen or input values. Optional
+ * parameters which were not selected are not included.
*
* @return
*/
List<ArgumentI> argSet = new ArrayList<>();
for (OptionBox opts : getOptSet().values())
{
- OptionI opt = opts.getOptionIfEnabled();
+ ArgumentI opt = opts.getSelectedOption();
if (opt != null)
{
argSet.add(opt);
}
for (ParamBox parambox : getParamSet().values())
{
- ParameterI parm = parambox.getParameter();
+ ArgumentI parm = parambox.getParameter();
if (parm != null)
{
argSet.add(parm);
return argSet;
}
+ /**
+ * A helper method that constructs and returns a CombBox for choice of the
+ * possible option values. If display names are provided, then these are added
+ * as options, otherwise the actual values are added.
+ *
+ * @param opt
+ * @return
+ */
+ protected static JComboBox<Object> buildComboBox(OptionI opt)
+ {
+ JComboBox<Object> cb = null;
+ List<String> displayNames = opt.getDisplayNames();
+ if (displayNames != null)
+ {
+ List<Object> displayNamesObjects = new ArrayList<>();
+ displayNamesObjects.addAll(displayNames);
+ cb = JvSwingUtils.buildComboWithTooltips(displayNamesObjects,
+ opt.getPossibleValues());
+ }
+ else
+ {
+ cb = new JComboBox<>();
+ for (String v : opt.getPossibleValues())
+ {
+ cb.addItem(v);
+ }
+ }
+ return cb;
+ }
+
+ /**
+ * Answers the value corresponding to the selected item in the choice combo
+ * box. Note that this returns the underlying value even if a different
+ * display name is used in the combo box.
+ *
+ * @return
+ */
+ protected static String getSelectedValue(OptionI opt, int sel)
+ {
+ List<String> possibleValues = opt.getPossibleValues();
+ String value = null;
+ if (possibleValues != null && possibleValues.size() == 1)
+ {
+ // Hack to make sure the default value for an enabled option with only
+ // one value is actually returned even if this.val is not displayed
+ value = possibleValues.get(0);
+ }
+ else if (sel >= 0 && sel < possibleValues.size())
+ {
+ value = possibleValues.get(sel);
+ }
+ return value;
+ }
}