--- /dev/null
+package jalview.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.ContainerEvent;
+import java.awt.event.ContainerListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.event.WindowStateListener;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.CellEditorListener;
+import javax.swing.table.*;
+
+import compbio.metadata.Argument;
+import compbio.metadata.Option;
+import compbio.metadata.Parameter;
+import compbio.metadata.Preset;
+import compbio.metadata.PresetManager;
+import compbio.metadata.RunnerConfig;
+import compbio.metadata.ValueConstrain;
+import compbio.metadata.ValueConstrain.Type;
+
+import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.jws2.Jws2Discoverer.Jws2Instance;
+
+public class WsJobParameters extends JPanel
+{
+ JPanel setDetails = new JPanel();
+
+ JPanel settingsPanel = new JPanel();
+
+ JPanel jobOptions = new JPanel();
+
+ JPanel jobParameters = new JPanel();
+
+ JPanel paramButtons = new JPanel();
+
+ JButton exportParams = new JButton();
+
+ JButton importParams = new JButton();
+
+ JButton resetParams = new JButton();
+
+ JButton addParam = new JButton();
+
+ JButton removeParam = new JButton();
+
+ JButton editParam = new JButton();
+
+ JLabel setName = new JLabel();
+
+ JTextArea setDescr = new JTextArea();
+
+ JTable paramTable = new JTable();
+
+ JScrollPane paramPane = new JScrollPane();
+
+ RunnerConfig serviceOptions;
+
+ List<Parameter> availableParameters;
+
+ private BorderLayout jparamLayout;
+
+ WsJobParameters(Jws2Instance service)
+ {
+ this(service, null);
+ }
+
+ public WsJobParameters(Jws2Instance service, Preset p)
+ {
+ this(null, service, p);
+ }
+
+ /**
+ *
+ * @param desktop
+ * - if null, create new JFrame outside of desktop
+ * @param service
+ * @param p
+ */
+ public WsJobParameters(JFrame parent, Jws2Instance service, Preset p)
+ {
+ super();
+ jbInit();
+ initTableUI();
+ // populate parameter table
+ initForService(service, p);
+ // display in new JFrame attached to parent.
+ validate();
+ }
+
+ private void jbInit()
+ {
+ exportParams.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ exportParams.setText("Export");
+ exportParams.setToolTipText("Export parameters to a file");
+ exportParams.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ exportParams_actionPerformed(e);
+ }
+ });
+ importParams.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ importParams.setText("Import");
+ importParams.setToolTipText("Import parameters from a file");
+ importParams.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ importParams_actionPerformed(e);
+ }
+ });
+ resetParams.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ resetParams.setText("Defaults");
+ resetParams.setToolTipText("Reset to defaults");
+ resetParams.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ resetParams_actionPerformed(e);
+ }
+ });
+ addParam.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ addParam.setText("Add");
+ addParam.setToolTipText("Add new parameter");
+ addParam.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ addParam_actionPerformed(e);
+ }
+ });
+ removeParam.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ removeParam.setText("Remove");
+ removeParam.setToolTipText("Remove selected parameter");
+ removeParam.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ removeParam_actionPerformed(e);
+ }
+ });
+ editParam.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
+ editParam.setText("Edit");
+ editParam.setToolTipText("Edit selected parameter");
+ editParam.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ editParam_actionPerformed(e);
+ }
+ });
+
+ setDetails.setBorder(new TitledBorder("Details"));
+ setDetails.setLayout(new GridLayout(2, 1));
+ setDescr.setColumns(40);
+ setDescr.setWrapStyleWord(true);
+ setDescr.setPreferredSize(new Dimension(350, 100));
+ setDetails.add(setName);
+ setDetails.add(setDescr);
+ setDetails.setPreferredSize(new Dimension(360, 150));
+ settingsPanel.setLayout(new BorderLayout());
+ jobOptions.setBorder(new TitledBorder("Options"));
+ jobParameters.setBorder(new TitledBorder("Parameters"));
+ jobParameters.setLayout(jparamLayout = new BorderLayout());
+ paramPane.setPreferredSize(new Dimension(360, 300));
+ paramButtons.setLayout(new GridLayout(2, 3));
+ paramButtons.add(addParam);
+ paramButtons.add(editParam);
+ paramButtons.add(removeParam);
+ // TODO: relayout buttons nicely
+ paramButtons.add(exportParams);
+ paramButtons.add(importParams);
+ paramButtons.add(resetParams);
+ jobParameters.add(paramPane, BorderLayout.NORTH);
+ jobParameters.add(paramButtons, BorderLayout.SOUTH);
+ settingsPanel.add(jobOptions, BorderLayout.NORTH);
+ settingsPanel.add(jobParameters, BorderLayout.SOUTH);
+ setLayout(new BorderLayout());
+ setPreferredSize(new Dimension(400, 600));
+ setSize(new Dimension(400, 600));
+ add(setDetails, BorderLayout.NORTH);
+ add(settingsPanel, BorderLayout.CENTER);
+ }
+
+ /**
+ * need to populate table and validate after calling this to set up table and
+ * add it to pane
+ */
+ public void initTableUI()
+ {
+ paramTable = new JTable();
+ paramTable.getTableHeader()
+ .setFont(new Font("Verdana", Font.PLAIN, 12));
+ paramTable.setFont(new Font("Verdana", Font.PLAIN, 12));
+
+ paramPane.getViewport().removeAll();
+ paramPane.getViewport().add(paramTable);
+ paramTable.setDefaultRenderer(Argument.class, new ArgumentRenderer());
+ paramTable.setDefaultRenderer(Parameter.class, new ArgumentRenderer());
+ paramTable.setDefaultRenderer(Option.class, new ArgumentRenderer());
+ paramTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ paramTable.addMouseListener(new MouseListener()
+ {
+
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() > 1)
+ {
+ editParam_actionPerformed(null);
+ }
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e)
+ {
+ // tooltips
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e)
+ {
+ // tooltips
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+ // paramTable.setDefaultEditor(Argument.class, new WsArgumentEditor(this));
+ }
+
+ public class WsArgumentEditor implements TableCellEditor
+ {
+
+ int p;
+
+ Argument arg;
+
+ WsJobParameters wsparm;
+
+ public WsArgumentEditor(WsJobParameters wsJobParameters)
+ {
+ wsparm = wsJobParameters;
+ p = wsparm.paramTable.getSelectedRow();
+ arg = (Argument) wsparm.paramTable.getValueAt(p, wsparm.paramTable
+ .getSelectedColumn());
+ /*
+ * if (arg instanceof Option) { if
+ * (JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ * "Remove option "+arg.getName(),
+ * "Delete option ?",JOptionPane.YES_NO_OPTION,
+ * JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
+ *
+ * } }
+ */
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table,
+ Object value, boolean isSelected, int row, int column)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void addCellEditorListener(CellEditorListener l)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void cancelCellEditing()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Object getCellEditorValue()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean isCellEditable(EventObject anEvent)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void removeCellEditorListener(CellEditorListener l)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean shouldSelectCell(EventObject anEvent)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean stopCellEditing()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+ protected void editParam_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void removeParam_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void addParam_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void resetParams_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void importParams_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected void exportParams_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ void initForService(Jws2Instance service, Preset p)
+ {
+ serviceOptions = service.getRunnerConfig();
+ updateTable(p);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateTable(Preset p)
+ {
+ WsParameterTableModel mdl = null;
+ TableModel tmdl = paramTable.getModel();
+ if (tmdl instanceof WsParameterTableModel)
+ {
+ mdl = (WsParameterTableModel) tmdl;
+ }
+ if (mdl == null)
+ {
+ paramTable.setModel(mdl = new WsParameterTableModel());
+ }
+ availableParameters = new ArrayList<Parameter>();
+ List<Parameter> setargs = new ArrayList<Parameter>();
+ // populate table from default parameter set.
+ List<Argument> args = serviceOptions.getArguments();
+
+ // split to params and required arguments
+ {
+ for (Argument arg : args)
+ {
+ Argument myarg = (Argument) arg;
+ // Ideally, Argument would implement isRequired !
+ if (myarg instanceof Parameter)
+ {
+ Parameter parm = (Parameter) myarg;
+ if (parm.isRequired())
+ {
+ setargs.add(parm);
+ }
+ else
+ {
+ availableParameters.add(parm);
+ }
+ }
+ else
+ {
+ if (myarg instanceof Option)
+ {
+ Option opt = (Option) myarg;
+ addOption(opt);
+ if (opt.isRequired())
+ {
+ selectOption(opt, opt.getDefaultValue());
+ }
+ }
+ else
+ {
+ System.err.println("Ignoring unknown service argument type "
+ + arg.getClass().getName());
+ }
+ }
+ }
+ }
+
+ if (p != null)
+ {
+ setDescr.setText(p.getDescription());
+ setName.setText(p.getName());
+ // TODO - URL link
+ try
+ {
+ args = p.getArguments(serviceOptions);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ setargs.clear();
+ // get setargs from current object
+ if (args != null)
+ {
+ for (Argument arg : args)
+ {
+ if (arg instanceof Parameter)
+ {
+ setargs.add((Parameter) arg);
+ }
+ else
+ {
+ if (arg instanceof Option)
+ {
+ selectOption((Option) arg, arg.getDefaultValue());
+ }
+ }
+
+ }
+ }
+ }
+
+ mdl.setData(setargs);
+ paramTable.setModel(mdl);
+ // paramTable.validate();
+ jobOptions.setLayout(new GridLayout(optSet.size() / 2 + 1, 2));
+ jobOptions.validate();
+ }
+
+ private void selectOption(Option opt, String string)
+ {
+ OptionBox cb = optSet.get(opt.getName());
+ if (cb == null)
+ {
+ cb = addOption(opt);
+ }
+ if (string == null)
+ {
+ // no value specified.
+ if (opt.isRequired())
+ {
+ // indicate option needs to be selected!
+ }
+ else
+ {
+ cb.enabled.setSelected(false);
+ }
+ }
+ else
+ {
+ cb.enabled.setSelected(true);
+
+ if (opt.getPossibleValues().contains(string))
+ {
+ cb.val.setSelectedItem(string);
+ }
+ else
+ {
+ throw new Error("Invalid value " + string + " for option " + opt);
+ }
+
+ }
+ }
+
+ Map<String, OptionBox> optSet = new Hashtable<String, OptionBox>();
+
+ public class OptionBox extends JPanel
+ {
+ JComboBox val = new JComboBox();
+
+ JCheckBox enabled = new JCheckBox();
+
+ public OptionBox(Option opt)
+ {
+ setLayout(new BorderLayout());
+ enabled.setSelected(opt.isRequired());
+ enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
+ enabled.setText(opt.getName());
+ enabled.setToolTipText(opt.getDescription());
+ add(enabled, BorderLayout.NORTH);
+ if (opt.getPossibleValues().size() > 1)
+ {
+ setLayout(new GridLayout(1,2));
+ for (Object str : opt.getPossibleValues())
+ {
+ val.addItem((String) str);
+ }
+ val.setSelectedItem((String) opt.getDefaultValue());
+ 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.
+ }
+ }
+
+ private OptionBox addOption(Option opt)
+ {
+ OptionBox cb = optSet.get(opt.getName());
+ if (cb == null)
+ {
+ cb = new OptionBox(opt);
+ optSet.put(opt.getName(), cb);
+ jobOptions.add(cb);
+ }
+ return cb;
+ }
+
+ class WsParameterTableModel extends AbstractTableModel
+ {
+ // arg list - vector for thread safety
+ public Vector<Parameter> data = new Vector<Parameter>();
+
+ private String[] colNames =
+ { "Parameter", "Value" };
+
+ @Override
+ public int getColumnCount()
+ {
+ return 2;
+ }
+
+ @Override
+ public int findColumn(String columnName)
+ {
+ // TODO Auto-generated method stub
+ return super.findColumn(columnName);
+ }
+
+ public void setData(List<Parameter> setargs)
+ {
+ if (setargs != null)
+ {
+ data = new Vector<Parameter>(setargs);
+
+ }
+ else
+ {
+ data = new Vector<Parameter>();
+ }
+ }
+
+ public List<Parameter> getData()
+ {
+ return new ArrayList<Parameter>(data);
+ }
+
+ @Override
+ public int getRowCount()
+ {
+ return data.size();
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ if (rowIndex >= 0 && rowIndex < data.size())
+ {
+ Parameter prm = data.elementAt(rowIndex);
+ switch (columnIndex)
+ {
+ case 0:
+ return prm.getName();
+ case 1:
+ Object exc = null;
+ // the accessor name for the parameter value is possibly confusing
+ String val = prm.getDefaultValue();
+ try
+ {
+ if (prm.getValidValue().getType().equals(Type.Float))
+ {
+ exc = new Float(0);
+ return Float.parseFloat(val);
+ }
+ if (prm.getValidValue().getType().equals(Type.Integer))
+ {
+ exc = new Integer(0);
+ return Integer.parseInt(val);
+ }
+ } catch (NumberFormatException e)
+ {
+ return exc;
+ }
+ // must be a string
+ return val;
+
+ default:
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
+ */
+ @Override
+ public Class<?> getColumnClass(int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0:
+ return String.class;
+ case 1:
+ return Parameter.class;
+ }
+ return super.getColumnClass(columnIndex);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.swing.table.AbstractTableModel#getColumnName(int)
+ */
+ @Override
+ public String getColumnName(int column)
+ {
+ return colNames[column];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
+ */
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ if (columnIndex == 1)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ class ArgumentRenderer implements TableCellRenderer
+ {
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column)
+ {
+ if (value instanceof Option)
+ {
+ JCheckBox cb = new JCheckBox();
+ cb.setSelected(true);
+ return cb;
+ }
+ if (value instanceof Boolean)
+ {
+ JCheckBox cb = new JCheckBox();
+ cb.setSelected(((Boolean) value).booleanValue());
+ return cb;
+ }
+ if (value instanceof String)
+ {
+ JLabel lbl = new JLabel();
+ lbl.setFont(new Font("Verdana", Font.PLAIN, 11));
+ lbl.setText((String) value);
+ return lbl;
+ }
+ if (value instanceof Parameter)
+ {
+ String val = ((Parameter) value).getDefaultValue();
+ ValueConstrain constr = ((Parameter) value).getValidValue();
+ JLabel lbl = new JLabel();
+ lbl.setFont(new Font("Verdana", Font.PLAIN, 11));
+ lbl.setText(val);
+ return lbl;
+ /*
+ * type dependent return value if
+ * (constr.getType().equals(Type.Integer))
+ *
+ * { lbl.setText(val); } if (constr.getType().equals(Type.Float)) { }
+ * return lbl;
+ */
+ }
+ return null;
+ }
+ }
+
+ /**
+ * testing method - grab a service and parameter set and show the window
+ *
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
+ .getDiscoverer();
+ int p = 0;
+ if (args.length > 3)
+ {
+ Vector<String> services = new Vector<String>();
+ services.addElement(args[p++]);
+ Jws2Discoverer.setServiceUrls(services);
+ }
+ try
+ {
+ disc.run();
+ } catch (Exception e)
+ {
+ System.err.println("Aborting. Problem discovering services.");
+ e.printStackTrace();
+ return;
+ }
+ Jws2Discoverer.Jws2Instance lastserv = null;
+ for (Jws2Discoverer.Jws2Instance service : disc.getServices())
+ {
+ lastserv = service;
+ if (p < args.length && service.serviceType.equalsIgnoreCase(args[p]))
+ {
+ break;
+ }
+ }
+ if (lastserv != null)
+ {
+ Preset pr = null;
+ if (++p < args.length)
+ {
+ PresetManager prman = lastserv.getPresets();
+ if (prman != null)
+ {
+ pr = prman.getPresetByName(args[p]);
+ if (pr == null)
+ {
+ // just grab the last preset.
+ List<Preset> prl = prman.getPresets();
+ pr = prl.get(prl.size() - 1);
+ }
+ }
+ }
+ while (true)
+ {
+ WsJobParameters pgui = new WsJobParameters(lastserv, pr);
+ JFrame jf = new JFrame("Parameters for " + lastserv.getActionText());
+ JPanel cont = new JPanel();
+ cont.setSize(new Dimension(600, 800));
+ cont.add(pgui);
+ jf.add(cont);
+ final Thread thr = Thread.currentThread();
+ jf.addWindowListener(new WindowListener()
+ {
+
+ @Override
+ public void windowActivated(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowClosed(WindowEvent e)
+ {
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e)
+ {
+ thr.interrupt();
+
+ }
+
+ @Override
+ public void windowDeactivated(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowDeiconified(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowIconified(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowOpened(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+ jf.setVisible(true);
+ boolean inter = false;
+ while (!inter)
+ {
+ try
+ {
+ Thread.sleep(10000);
+ } catch (Exception e)
+ {
+ inter = true;
+ }
+ ;
+ }
+ jf.dispose();
+ }
+ }
+ }
+}