*/
package jalview.gui;
-import static jalview.ws.params.simple.LogarithmicParameter.LOGSLIDERSCALE;
-
-import jalview.bin.Cache;
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.simple.StringParameter;
import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
public class OptionBox extends JPanel
implements MouseListener, ActionListener
{
- JCheckBox enabled = new JCheckBox();
+ JCheckBox enabled;
final URL finfo;
OptionI option;
- JLabel optlabel = new JLabel();
-
- JComboBox<String> val = new JComboBox<>();
+ JComboBox<String> val;
+ /**
+ * Constructs and adds labels and controls to the panel for one Option
+ *
+ * @param opt
+ */
public OptionBox(OptionI opt)
{
option = opt;
setLayout(new FlowLayout(FlowLayout.LEFT));
- enabled.setSelected(opt.isRequired()); // TODO: lock required options
- enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
- enabled.setText("");
- enabled.setText(opt.getName());
- enabled.addActionListener(this);
- finfo = option.getFurtherDetails();
- String desc = opt.getDescription();
- if (finfo != null)
+ enabled = new JCheckBox(opt.getName());
+ 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))
{
- 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);
+ finfo = null;
+ add(new JLabel(opt.getName()));
}
else
{
- if (desc != null && desc.trim().length() > 0)
- {
- enabled.setToolTipText(
- JvSwingUtils.wrapTooltip(true, opt.getDescription()));
- }
- }
- add(enabled);
- for (String str : opt.getPossibleValues())
- {
- val.addItem(str);
+ 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);
}
- // 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();
}
+ /**
+ * 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.addActionListener(this);
+ final String desc = opt.getDescription();
+ if (finfo != null)
+ {
+ hasLink = true;
+ 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, desc));
+ }
+ }
+ }
+
@Override
public void actionPerformed(ActionEvent e)
{
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;
}
public class ParamBox extends JPanel
implements ChangeListener, ActionListener, MouseListener
{
- private static final float SLIDERSCALE = 1000f;
+ /*
+ * 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 isIntegerParameter;
+ boolean isStringParameter;
+
boolean adjusting;
JComboBox<String> choicebox;
finfo = parm.getFurtherDetails();
validator = parm.getValidValue();
parameter = parm;
+
+ isLogarithmicParameter = parm instanceof LogarithmicParameter;
+
if (validator != null)
{
- isIntegerParameter = validator.getType() == ValueType.Integer;
- }
- else if (parameter.getPossibleValues() != null)
- {
- isChoiceParameter = true;
- }
- if (parm instanceof LogarithmicParameter)
- {
- isLogarithmicParameter = true;
+ ValueType type = validator.getType();
+ isIntegerParameter = type == ValueType.Integer;
+ isStringParameter = type == ValueType.String;
+
+ /*
+ * ensure slider has an integer range corresponding to
+ * the min-max range of the parameter
+ */
+ if (validator.getMin() != null && validator.getMax() != null
+ // && !isIntegerParameter
+ && !isStringParameter)
+ {
+ 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
+ }
}
+ List<String> possibleValues = parameter.getPossibleValues();
+ isChoiceParameter = possibleValues != null
+ && !possibleValues.isEmpty();
+
if (compact)
{
addCompactParameter(parm);
*/
private void checkIfModified()
{
- Object newValue = updateSliderFromValueField();
- boolean modified = true;
- if (newValue.getClass() == lastVal.getClass())
+ if (!adjusting)
{
- modified = !newValue.equals(lastVal);
+ try
+ {
+ adjusting = true;
+ Object newValue = updateSliderFromValueField();
+ boolean modified = true;
+ if (newValue.getClass() == lastVal.getClass())
+ {
+ modified = !newValue.equals(lastVal);
+ }
+ pmdialogbox.argSetModified(this, modified);
+ } finally
+ {
+ adjusting = false;
+ }
}
- pmdialogbox.argSetModified(this, modified);
}
@Override
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
- public ParameterI getParameter()
+ /**
+ * Answers an argument holding the value entered or selected in the dialog
+ *
+ * @return
+ */
+ public ArgumentI getParameter()
{
ParameterI prm = parameter.copy();
if (isChoiceParameter)
{
- prm.setValue((String) choicebox.getSelectedItem());
+ String value = getSelectedValue(this.parameter, choicebox.getSelectedIndex());
+ prm.setValue(value);
}
else
{
@Override
public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void mouseExited(MouseEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
@Override
public void mouseReleased(MouseEvent e)
{
- // TODO Auto-generated method stub
-
}
@Override
public void stateChanged(ChangeEvent e)
{
- if (!adjusting)
+ if (adjusting)
+ {
+ return;
+ }
+ try
{
+ adjusting = true;
if (!isLogarithmicParameter)
{
/*
* set (int or float formatted) text field value
*/
- valueField.setText(isIntegerParameter ? String.valueOf(slider.getValue())
- : String.valueOf(slider.getValue() / SLIDERSCALE));
+ valueField.setText(isIntegerParameter
+ ? String.valueOf(slider.getValue())
+ : formatDouble(
+ slider.getValue() / (float) sliderScaleFactor));
}
else
{
- double base = ((LogarithmicParameter) parameter).getBase();
- double value = Math.pow(base, slider.getValue() / LOGSLIDERSCALE);
+ double value = Math.pow(Math.E,
+ slider.getValue() / (double) sliderScaleFactor);
valueField.setText(formatDouble(value));
}
checkIfModified();
+ } finally
+ {
+ adjusting = false;
}
-
}
/**
*/
String formatDouble(double value)
{
- String format = value < 0.001 ? "%3.3e" : "%3.3f";
+ 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;
{
if (isChoiceParameter)
{
- choicebox = new JComboBox<>();
- choicebox.addActionListener(this);
+ choicebox = buildComboBox(parm);
controlsPanel.add(choicebox, BorderLayout.CENTER);
}
else
@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)
{
}
}
});
- valueField.setPreferredSize(new Dimension(60, 25));
+ valueField.setPreferredSize(new Dimension(65, 25));
controlsPanel.add(slider, BorderLayout.WEST);
controlsPanel.add(valueField, BorderLayout.EAST);
}
}
- if (parm != null)
+ if (!isChoiceParameter && parm != null)
{
- if (isChoiceParameter)
- {
- if (init)
- {
- for (String val : parm.getPossibleValues())
- {
- choicebox.addItem(val);
- }
- }
-
- if (parm.getValue() != null)
- {
- choicebox.setSelectedItem(parm.getValue());
- }
- }
- else
- {
- if (parm instanceof LogarithmicParameter)
- {
- double base = ((LogarithmicParameter) parm).getBase();
- // double value = Math.pow(base,
- // Double.parseDouble(parm.getValue()) / LOGSLIDERSCALE);
- double value = Double.parseDouble(parm.getValue());
- valueField.setText(formatDouble(value));
- }
- else
- {
- valueField.setText(parm.getValue());
- }
- }
+ valueField.setText(parm.getValue());
}
lastVal = updateSliderFromValueField();
adjusting = false;
*/
Object updateSliderFromValueField()
{
- if (validator == null)
+ if (validator == null || isStringParameter)
{
- if (!isChoiceParameter)
+ if (isChoiceParameter)
{
- slider.setVisible(false);
- return valueField.getText().trim();
+ return getSelectedValue(this.parameter, choicebox.getSelectedIndex());
}
- else
+ slider.setVisible(false);
+ return valueField.getText().trim();
+ }
+
+ 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)
{
- return choicebox.getSelectedItem();
+ valueField.setText(formatNumber(validator.getMax()));
}
+ } catch (NumberFormatException e)
+ {
+ valueField.setBackground(Color.yellow);
+ return Float.NaN;
}
+
if (isIntegerParameter)
{
int iVal = 0;
try
{
- valueField.setText(valueField.getText().trim());
iVal = Integer.valueOf(valueField.getText());
-
- /*
- * ensure not outside min-max range
- * TODO: provide some visual indicator if limit reached
- */
- if (validator.getMin() != null
- && validator.getMin().intValue() > iVal)
- {
- iVal = validator.getMin().intValue();
- valueField.setText(String.valueOf(iVal));
- }
- if (validator.getMax() != null
- && validator.getMax().intValue() < iVal)
- {
- iVal = validator.getMax().intValue();
- valueField.setText(String.valueOf(iVal));
- }
} catch (Exception e)
{
- Cache.log.error(e.getMessage());
+ valueField.setBackground(Color.yellow);
+ return Integer.valueOf(0);
}
if (validator.getMin() != null && validator.getMax() != null)
}
return new Integer(iVal);
}
- else if (isLogarithmicParameter)
+
+ if (isLogarithmicParameter)
{
double dVal = 0d;
try
{
- valueField.setText(valueField.getText().trim());
double eValue = Double.valueOf(valueField.getText());
-
- dVal = Math.log(eValue)
- / Math.log(((LogarithmicParameter) parameter).getBase())
- * LOGSLIDERSCALE;
-
- /*
- * ensure not outside min-max range
- * TODO: provide some visual indicator if limit reached
- */
- if (validator.getMin() != null
- && validator.getMin().doubleValue() > dVal)
- {
- dVal = validator.getMin().doubleValue();
- valueField.setText(formatDouble(eValue));
- }
- if (validator.getMax() != null
- && validator.getMax().doubleValue() < dVal)
- {
- dVal = validator.getMax().doubleValue();
- valueField.setText(formatDouble(eValue));
- }
+ dVal = Math.log(eValue) * sliderScaleFactor;
} 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) (dVal), 1,
- (int) (validator.getMin().doubleValue()),
- 1 + (int) (validator.getMax().doubleValue()), true);
+ (int) scaleMin, 1 + (int) scaleMax, true);
}
else
{
}
return new Double(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
{
- float fVal = 0f;
- try
- {
- valueField.setText(valueField.getText().trim());
- fVal = Float.valueOf(valueField.getText());
-
- /*
- * ensure not outside min-max range
- * TODO: provide some visual indicator if limit reached
- */
- if (validator.getMin() != null
- && validator.getMin().floatValue() > fVal)
- {
- fVal = validator.getMin().floatValue();
- valueField.setText(String.valueOf(fVal));
- }
- if (validator.getMax() != null
- && validator.getMax().floatValue() < fVal)
- {
- fVal = validator.getMax().floatValue();
- valueField.setText(String.valueOf(fVal));
- }
- } catch (Exception e)
- {
- }
-
- if (validator.getMin() != null && validator.getMax() != null)
- {
- slider.getModel().setRangeProperties((int) (fVal * SLIDERSCALE),
- 1, (int) (validator.getMin().floatValue() * SLIDERSCALE),
- 1 + (int) (validator.getMax().floatValue() * SLIDERSCALE),
- true);
- }
- else
- {
- slider.setVisible(false);
- }
- return new Float(fVal);
+ slider.setVisible(false);
}
+ return new Float(fVal);
}
}
}
/**
- * 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 JComboBox<String> buildComboBox(OptionI opt)
+ {
+ JComboBox<String> cb = null;
+ List<String> displayNames = opt.getDisplayNames();
+ if (displayNames != null)
+ {
+ cb = JvSwingUtils.buildComboWithTooltips(displayNames,
+ 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. If display names were not provided, this is simply the selected
+ * value. If display names were provided, it is the value corresponding to
+ * the selected item index.
+ *
+ * @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);
+ }
+ else
+ {
+ value = opt.getValue();
+ }
+ }
+ return value;
+ }
}