package jalview.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; 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.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; 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.Iterator; 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.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.TitledBorder; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; 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.WrongParameterException; import compbio.metadata.ValueConstrain.Type; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.Jws2Discoverer.Jws2Instance; public class WsJobParameters extends JPanel { private static final int PARAM_WIDTH = 340, PARAM_HEIGHT = 120; JPanel setDetails = new JPanel(); JPanel settingsPanel = new JPanel(); JPanel jobOptions = new JPanel(); JPanel jobParameters = new JPanel(); JPanel paramButtons = new JPanel(); JPanel paramPanel = new JPanel(); JLabel modified = new JLabel(); JButton startjob = new JButton(); JButton canceljob = new JButton(); 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(); JScrollPane paramPane = new JScrollPane(); // JList paramList = new JList(); JPanel paramList = new JPanel(); RunnerConfig serviceOptions; List availableParameters; private BorderLayout jparamLayout; WsJobParameters(Jws2Instance service) { this(service, null); } public WsJobParameters(Jws2Instance service, Preset p) { this(null, service, p, null); } /** * * @param desktop * - if null, create new JFrame outside of desktop * @param service * @param p */ public WsJobParameters(JFrame parent, Jws2Instance service, Preset p, List jobArgset) { super(); jbInit(); argSetModified(false); // populate parameter table initForService(service, p, jobArgset); // display in new JFrame attached to parent. validate(); } int response=-1; JDialog frame=null; public boolean showRunDialog() { frame = new JDialog( Desktop.instance, true); frame.setTitle("Edit parameters for "+service.getActionText()); Rectangle deskr = Desktop.instance.getBounds(); frame.setBounds(new Rectangle((int) (deskr.getCenterX() - 240), (int) (deskr.getCenterY() - 92), 380, 385)); frame.setContentPane(this); frame.setVisible(true); if (response>0) { return true; } return false; } private void jbInit() { modified.setText("Job Options Modified"); modified.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10)); modified.setForeground(Color.red); modified.setHorizontalAlignment(SwingConstants.CENTER); 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); } }); startjob.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10)); startjob.setText("Start"); startjob.setToolTipText("Start Job"); startjob.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { startjob_actionPerformed(e); } }); canceljob.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10)); canceljob.setText("Cancel"); canceljob.setToolTipText("Cancel Job"); canceljob.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { canceljob_actionPerformed(e); } }); setDetails.setBorder(new TitledBorder("Details")); setDetails.setLayout(new GridLayout(2, 1)); setDescr.setColumns(40); setDescr.setWrapStyleWord(true); setDescr.setLineWrap(true); setDescr.setPreferredSize(new Dimension(350, 90)); setDescr.setBackground(getBackground()); setDescr.setEditable(false); setDetails.add(setName); setDetails.add(setDescr); setDetails.setPreferredSize(new Dimension(360, 100)); 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)); paramPane.getVerticalScrollBar().setUnitIncrement(20); // paramPanel.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); paramPane.getViewport().setView(paramList); jobParameters.add(paramPane, BorderLayout.NORTH); //jobParameters.add(paramButtons, BorderLayout.SOUTH); settingsPanel.add(modified, BorderLayout.NORTH); settingsPanel.add(jobOptions, BorderLayout.CENTER); 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); JPanel dialogpanel = new JPanel(); dialogpanel.add(startjob); dialogpanel.add(canceljob); add(dialogpanel, BorderLayout.SOUTH); } protected void canceljob_actionPerformed(ActionEvent e) { response=0; if (frame!=null) { frame.setVisible(false); } } protected void startjob_actionPerformed(ActionEvent e) { response=1; if (frame!=null) { frame.setVisible(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 } Jws2Instance service; void initForService(Jws2Instance service, Preset p, List jobArgset) { this.service=service; serviceOptions = service.getRunnerConfig(); updateTable(p, jobArgset); } @SuppressWarnings("unchecked") private void updateTable(Preset p, List jobArgset) { availableParameters = new ArrayList(); List setargs = new ArrayList(); // populate table from default parameter set. List 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 (true) // parm.isRequired()) { addParameter(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()); } } } args=null; // no more args to process. } if (p != null) { setDescr.setText(p.getDescription()); setName.setText(p.getName()); setDetails.setVisible(true); // TODO - URL link try { args = p.getArguments(serviceOptions); } catch (Exception e) { e.printStackTrace(); } // TODO: check if args should be unselected prior to resetting using the preset setargs.clear(); } else { setDetails.setVisible(false); } if (jobArgset != null) { argSetModified(true); args = jobArgset; } // 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); // jobOptions.setLayout(new GridLayout(optSet.size() / 2 + 1, 2)); jobOptions.setLayout(new GridLayout(optSet.size(), 1)); // paramPanel.setLayout(new GridLayout(paramSet.size(), 1)); // paramList.va // paramPane.getViewport().validate(); paramList.setPreferredSize(new Dimension(350, paramSet.size() * PARAM_HEIGHT)); paramList.setLayout(new GridLayout(paramSet.size(), 1)); paramList.validate(); paramPane.validate(); validate(); } private void argSetModified(boolean b) { modified.setVisible(b); if (isVisible()) { validate(); } } private void addParameter(Parameter parm) { ParamBox pb = paramSet.get(parm.getName()); if (pb == null) { pb = new ParamBox(parm); paramSet.put(parm.getName(), pb); paramList.add(pb); } } 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 paramSet = new Hashtable(); public class ParamBox extends JPanel implements ChangeListener, ActionListener { JLabel name = new JLabel(); JTextArea string = new JTextArea(); JScrollPane descPanel = new JScrollPane(); JSlider slider = null; JTextField valueField = null; ValueConstrain validator = null; boolean integ = false; boolean choice=false; public ParamBox(Parameter parm) { setLayout(new FlowLayout()); setBorder(new TitledBorder(parm.getName())); setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_HEIGHT)); string.setFont(new Font("Verdana", Font.PLAIN, 11)); string.setBackground(getBackground()); //string.setSize(new Dimension(PARAM_WIDTH, 80)); string.setEditable(false); descPanel.setPreferredSize(new Dimension(PARAM_WIDTH, 70)); descPanel.getViewport().setView(string); // string.setMinimumSize(new Dimension(140,80)); // string.setMaximumSize(new Dimension(280,80)); string.setWrapStyleWord(true); string.setLineWrap(true); string.setColumns(40); string.setText(parm.getDescription()); descPanel.validate(); // name.setToolTipText(parm.getDescription()); add(descPanel); // , BorderLayout.NORTH); validator = parm.getValidValue(); parameter=parm; if (validator != null) { integ = validator.getType() == Type.Integer; } else { if (parameter.getPossibleValues()!=null) { choice=true; } } updateControls(parm); } boolean adjusting = false; Parameter parameter; JComboBox choicebox; public void updateControls(Parameter parm) { adjusting = true; boolean init = valueField == null; float fVal = 0f; int iVal = 0; if (init) { if (choice) { choicebox = new JComboBox(); choicebox.addActionListener(this); add(choicebox); } else { slider = new JSlider(); slider.addChangeListener(this); valueField = new JTextField(); valueField.addActionListener(this); valueField.setPreferredSize(new Dimension(80, 25)); JPanel container = new JPanel(); // container.setLayout(new FlowLayout()); add(slider);// , BorderLayout.SOUTH); add(valueField);// ,BorderLayout.CENTER); // add(container, BorderLayout.EAST); // container.validate(); }} if (parm != null) { if (choice) { List vals = parm.getPossibleValues(); for (Object val: vals) { choicebox.addItem(val); } if (parm.getDefaultValue()!=null) { choicebox.setSelectedItem(parm.getDefaultValue()); } } else { valueField.setText(parm.getDefaultValue()); } } updateSliderFromValueField(); adjusting = false; } public Parameter getParameter() { try { if (choice) { parameter.setDefaultValue((String)choicebox.getSelectedItem()); } else { parameter.setDefaultValue(valueField.getText()); } } catch (WrongParameterException e) { e.printStackTrace(); return null; } return parameter; } public Object updateSliderFromValueField() { int iVal; float fVal; if (validator != null) { if (integ) { iVal = 0; try { valueField.setText(valueField.getText().trim()); iVal = Integer.valueOf(valueField.getText()); } catch (Exception e) { } ; if (validator.getMin() != null && validator.getMax() != null) { slider.getModel().setRangeProperties(iVal, 1, validator.getMin().intValue(), validator.getMax().intValue(), true); } else { slider.setVisible(false); } return new int[] { iVal }; } else { fVal = 0f; try { fVal = Float.valueOf(valueField.getText()); } catch (Exception e) { } ; if (validator.getMin() != null && validator.getMax() != null) { slider.getModel().setRangeProperties((int) fVal * 1000, 1, (int) validator.getMin().floatValue() * 1000, (int) validator.getMax().floatValue() * 1000, true); } else { slider.setVisible(false); } return new float[] { fVal }; } } else { if (!choice) { slider.setVisible(false); return new String[] { valueField.getText().trim() }; } else { return new String[] { (String) choicebox.getSelectedItem()}; } } } @Override public void stateChanged(ChangeEvent e) { if (!adjusting) { valueField.setText("" + ((integ) ? ("" + (int) slider.getValue()) : ("" + (float) (slider.getValue() / 1000f)))); } } @Override public void actionPerformed(ActionEvent e) { if (choice) { } else if (!adjusting) { updateSliderFromValueField(); } argSetModified(true); } } Map optSet = new Hashtable(); public class OptionBox extends JPanel implements ActionListener { JComboBox val = new JComboBox(); JCheckBox enabled = new JCheckBox(); Option option; public OptionBox(Option opt) { 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()); 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. } public Option getOptionIfEnabled() { if (!enabled.isSelected()) { return null; } try { if (val.getSelectedItem()!=null) { option.setDefaultValue((String) val.getSelectedItem()); } } catch (WrongParameterException e) { e.printStackTrace(); return null; } return option; } @Override public void actionPerformed(ActionEvent e) { argSetModified(true); enabled.setSelected(true); } } 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; } /** * 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 services = new Vector(); 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) { List prl = 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. prl = prman.getPresets(); } } } Iterator en = (prl == null) ? null : prl.iterator(); while (true) { if (en != null) { if (!en.hasNext()) { en = prl.iterator(); } pr = en.next(); } WsJobParameters pgui = new WsJobParameters(lastserv, pr); JFrame jf = new JFrame("Parameters for " + lastserv.getActionText()); JPanel cont = new JPanel(); jf.setPreferredSize(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(); } } } public List getJobParams() { List argSet = new ArrayList(); // recover options and parameters from GUI for (OptionBox opts: optSet.values()) { Option opt = opts.getOptionIfEnabled(); if (opt!=null) { argSet.add(opt); } } for (ParamBox parambox: paramSet.values()) { Parameter parm = parambox.getParameter(); if (parm!=null) { argSet.add(parm); } } return argSet; } }