gt:         PValue p = parammap.get(name);
context: package zcm.util;
  
  import java.util.*;
  import javax.swing.*;
  import javax.swing.event.*;
  import java.awt.*;
  import java.awt.event.*;
  
  public class ParameterGUI
  {
      HashMap<String, PValue> parammap = new HashMap<String, PValue>();
      JPanel  panel = new JPanel(new GridBagLayout());
      int     row = 0;
      GridBagConstraints gA, gB, gC, gD, gBC, gCD, gBCD, gABCD;
      ArrayList<ParameterListener> listeners = new ArrayList<ParameterListener>();
      boolean showvars;
  
      /** This makes a text field yellow until they've pressed return;
          it's a reminder that you need to hit return for the changes to
          your text field to apply.
      **/
      static void setupJTextField(JTextField jtf)
      {
          JTFListener l = new JTFListener(jtf);
          jtf.addActionListener(l);
          jtf.addCaretListener(l);
          jtf.addKeyListener(l);
      }
  
      static class JTFListener extends KeyAdapter implements ActionListener, CaretListener
      {
          JTextField jtf;
  
          JTFListener(JTextField jtf)
          {
              this.jtf=jtf;
          }
  
          public void keyPressed(KeyEvent e)
          {
              jtf.setBackground(Color.yellow);
          }
  
          public void actionPerformed(ActionEvent e)
          {
              jtf.setBackground(Color.white);
          }
  
          public void caretUpdate(CaretEvent e)
          {
          }
      }
  
      /** Parent interface of all value elements **/
      abstract class PValue
      {
          String name;  // name of element, e.g., "logthresh"
          String desc;  // description, e.g., "Logarithmic threshold"
  
          PValue(String name, String desc)
          {
              this.name = name;
              this.desc = desc;
          }
  
          abstract void setEnabled(boolean enabled);
      }
  
      /** parse the integer in string s, or if it fails, return 'default' **/
      static final int parseInteger(String s, int val)
      {
          try {
              return Integer.parseInt(s);
          } catch (Exception ex) {
              return val;
          }
      }
  
      /** parse the integer in string s, or if it fails, return 'default' **/
      static final double parseDouble(String s, double val)
      {
          try {
              return Double.parseDouble(s);
          } catch (Exception ex) {
              return val;
          }
      }
  
      class ActionNotifier implements ActionListener
      {
          String name;
  
          public ActionNotifier(String name)
          {
              this.name = name;
          }
  
          public void actionPerformed(ActionEvent e)
          {
              notifyListeners(name);
          }
      }
  
      class BooleanValue extends PValue
      {
          JCheckBox  jcb;
          boolean value;
  
          BooleanValue(String name, String desc, boolean value)
          {
              super(name, desc);
  
              this.value = value;
          }
  
          JCheckBox getCheckBox()
          {
              if (jcb == null)
              {
                  jcb = new JCheckBox(desc, value);
                  jcb.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                          setBooleanValue(jcb.isSelected());
                      }});
  
              }
              return jcb;
          }
  
          boolean getBooleanValue()
          {
              return value;
          }
  
          void setBooleanValue(boolean v)
          {
              if (v==value)
                  return;
  
              value = v;
              notifyListeners(name);
          }
  
          void setEnabled(boolean v)
          {
              jcb.setEnabled(v);
          }
      }
  
      class IntegerValue extends PValue
      {
          JSlider    slider;
          JTextField textField;
          JLabel     label;
          int        min, max;
          int        value;
  
          IntegerValue(String name, String desc, int min, int max, int value)
          {
              super(name, desc);
  
              this.min = min;
              this.max = max;
              this.value = value;
          }
  
          JSlider getSlider()
          {
              if (slider == null)
              {
                  slider = new JSlider(min, max, value);
                  slider.addChangeListener(new ChangeListener() {
                      public void stateChanged(ChangeEvent e) {
                          setIntegerValue(slider.getValue());
                      }});
              }
              return slider;
          }
  
          JLabel getLabel()
          {
              if (label == null)
                  label = new JLabel(""+value);
              return label;
          }
  
          JTextField getTextField()
          {
              if (textField == null) {
                  textField = new JTextField(""+value);
                  setupJTextField(textField);
                  textField.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                          setIntegerValue(parseInteger(textField.getText(), value));
                      }});
  
              }
              return textField;
          }
  
          int getIntegerValue()
          {
              return value;
          }
  
          void setIntegerValue(int v)
          {
              if (v<min)
                  v=min;
              if (v>max)
                  v=max;
              if (v == value)
                  return;
  
              value = v;
              if (slider != null)
                  slider.setValue(v);
              if (textField != null)
                  textField.setText(""+v);
              if (label != null)
                  label.setText(""+v);
  
              notifyListeners(name);
          }
  
          void setMinMax(int min, int max)
          {
              this.min = min;
              this.max = max;
              if (slider != null)
              {
                  slider.setMinimum(min);
                  slider.setMaximum(max);
              }
          }
  
          void setEnabled(boolean v)
          {
              if (slider!=null)
                  slider.setEnabled(v);
              if (textField!=null)
                  textField.setEnabled(v);
          }
      }
  
      class DoubleValue extends PValue
      {
          JSlider    slider;
          JTextField textField;
          JLabel     label;
          double     min, max;
          double     value;
          int        ivalue; // scaled values used for slider
          static final int SLIDER_CLICKS = 100000;
          double     stepsize;
          String     svalue; // string representation of value.
  
          DoubleValue(String name, String desc, double min, double max, double value)
          {
              super(name, desc);
  
              this.min = min;
              this.max = max;
              this.value = value;
  
              updateSliderValue();
          }
  
          void updateSliderValue()
          {
              ivalue = (int) (SLIDER_CLICKS*(value-min)/(max-min));
              if (slider != null)
                  slider.setValue(ivalue);
              stepsize = (max-min)/SLIDER_CLICKS;
          }
  
          JSlider getSlider()
          {
              if (slider == null)
              {
                  slider = new JSlider(0, SLIDER_CLICKS, ivalue);
                  slider.addChangeListener(new ChangeListener() {
                      public void stateChanged(ChangeEvent e) {
                          setDoubleValue(((double)slider.getValue()+.5)/SLIDER_CLICKS*(max-min)+min);
                      }});
              }
              return slider;
          }
  
          JLabel getLabel()
          {
              if (label == null)
                  label = new JLabel(""+value);
              return label;
          }
  
          JTextField getTextField()
          {
              if (textField == null) {
                  textField = new JTextField(""+value);
                  setupJTextField(textField);
                  textField.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                          setDoubleValue(parseDouble(textField.getText(), value));
                      }});
              }
  
              return textField;
          }
  
          double getDoubleValue()
          {
              return value;
          }
  
          void setDoubleValue(double v)
          {
              if (v<min)
                  v=min;
              if (v>max)
                  v=max;
              if (v == value)
                  return;
  
              value = v;
              updateSliderValue();
  
              {
                  int digits = (int) (-Math.log(stepsize)/Math.log(10))+1;
                  if (digits<0)
                      digits=0;
  
                  svalue=String.format("%."+digits+"f",value);
              }
  
              if (textField != null)
              {
                  textField.setText(svalue);
              }
              if (label != null)
              {
                  label.setText(svalue);
              }
  
              notifyListeners(name);
          }
  
          void setMinMax(double min, double max)
          {
              this.min = min;
              this.max = max;
              updateSliderValue();
          }
  
          void setEnabled(boolean v)
          {
              if (slider!=null)
                  slider.setEnabled(v);
              if (textField!=null)
                  textField.setEnabled(v);
          }
      }
  
      class StringValue extends PValue
      {
          JTextField textField;
          JComboBox  comboBox;
  
          String     value;
          String     values[];
          int        idx; // if values is set, idx is such that value=values[idx].
  
          public StringValue(String name, String desc, String values[], String value)
          {
              super(name, desc);
              this.value = value;
              this.values = values;
              updateIndex();
          }
  
          JTextField getTextField()
          {
              if (textField == null) {
                  textField = new JTextField(value);
                  setupJTextField(textField);
                  textField.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                          String v = textField.getText();
                          setStringValue(v);
                      }});
              }
              return textField;
          }
  
          JComboBox getComboBox()
          {
              assert(values != null);
  
              if (comboBox == null) {
                  comboBox = new JComboBox(values);
                  comboBox.addActionListener(new ActionListener() {
                      public void actionPerformed(ActionEvent e) {
                          setStringValue(values[comboBox.getSelectedIndex()]);
                      }});
                  comboBox.setSelectedIndex(idx);
              }
  
              return comboBox;
          }
  
          String getStringValue()
          {
              return value;
          }
  
          void updateIndex()
          {
              if (values!=null)
              {
                  idx = -1;
  
                  for (int i = 0; i < values.length; i++)
                  {
                      if (value.equals(values[i]))
                          idx = i;
                  }
  
                  if (idx == -1)
                      System.out.println("Warning: illegal string value specified: "+value);
              }
          }
  
          void setStringValue(String v)
          {
              if (v.equals(value))
                  return;
  
              value = v;
              updateIndex();
  
              if (textField != null)
                  textField.setText(v);
              if (comboBox != null)
                  comboBox.setSelectedIndex(idx);
  
              notifyListeners(name);
          }
  
          void setEnabled(boolean v)
          {
              if (textField!=null)
                  textField.setEnabled(v);
          }
      }
  
      /////////////////////////////////////////////////////////////////////////////
      public ParameterGUI()
      {
          this(true);
      }
  
      // Our grid:
      //
      //    0                1                   2       3
      //  AAAAA  BBBBBBBBBBBBBBBBBBBBBBBBBBBB  CCCCCC  DDDDDD
      //    gA               gB                  gC      gD
      //
      //  gCD spans columns C and D.
      //  gBCD spans columsn B, C, and D. (etc)
  
      public ParameterGUI(boolean showvars)
      {
          this.showvars = showvars;
  
          gA = new GridBagConstraints();
          gA.gridx = 0;
          gA.weightx = 0.05;
          gA.fill=GridBagConstraints.HORIZONTAL;
  
          gB = new GridBagConstraints();
          gB.gridx = 1;
          gB.weightx = 1;
          gB.fill=GridBagConstraints.HORIZONTAL;
  
          gC = new GridBagConstraints();
          gC.gridx = 2;
          gC.weightx = .1;
          gC.fill=GridBagConstraints.HORIZONTAL;
  
          gD = new GridBagConstraints();
          gD.gridx = 3;
          gD.weightx = .05;
          //	gD.fill=GridBagConstraints.HORIZONTAL;
          gD.anchor = GridBagConstraints.CENTER;
  
          gBC = new GridBagConstraints();
          gBC.gridx = 1;
          gBC.gridwidth = 2;
          gBC.weightx = gB.weightx + gC.weightx;
          gBC.fill=GridBagConstraints.HORIZONTAL;
  
          gCD = new GridBagConstraints();
          gCD.gridx = 2;
          gCD.gridwidth = 2;
          gCD.weightx = gC.weightx + gD.weightx;
          gCD.fill=GridBagConstraints.HORIZONTAL;
          gCD.anchor = GridBagConstraints.EAST;
  
          gBCD = new GridBagConstraints();
          gBCD.gridx = 1;
          gBCD.gridwidth = 3;
          gBCD.weightx = gB.weightx + gC.weightx + gD.weightx;
          gBCD.fill=GridBagConstraints.HORIZONTAL;
          gBCD.anchor = GridBagConstraints.EAST;
  
          gABCD = new GridBagConstraints();
          gABCD.gridx = 0;
          gABCD.gridwidth = 4;
          gABCD.weightx = gA.weightx + gB.weightx + gC.weightx + gD.weightx;
          gABCD.fill=GridBagConstraints.HORIZONTAL;
      }
  
      protected void notifyListeners(String name)
      {
          for (ParameterListener pl : listeners)
              pl.parameterChanged(name);
      }
  
      public void addListener(ParameterListener l)
      {
          listeners.add(l);
      }
  
      public void removeListeners()
      {
          listeners.clear();
      }
  
      public void addInt(String name, String desc, int value)
      {
          addInt(name, desc, -Integer.MAX_VALUE, Integer.MAX_VALUE, value);
      }
  
      public void addInt(String name, String desc, int min, int max, int value)
      {
          IntegerValue val = new IntegerValue(name, desc, -Integer.MAX_VALUE, Integer.MAX_VALUE, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBCD.gridy = row;
          panel.add(new JLabel(desc), gA);
          panel.add(val.getTextField(), gBCD);
          row++;
      }
  
      public void addIntSlider(String name, String desc, int min, int max, int value)
      {
          IntegerValue val = new IntegerValue(name, desc, min, max, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBC.gridy = row;
          gD.gridy = row;
  
          panel.add(new JLabel(desc), gA);
          panel.add(val.getSlider(), gBC);
          panel.add(val.getLabel(), gD);
          row++;
      }
  
      public void addDouble(String name, String desc, double value)
      {
          addDouble(name, desc, -Double.MAX_VALUE, Double.MAX_VALUE, value);
      }
  
      public void addDouble(String name, String desc, double min, double max, double value)
      {
          DoubleValue val = new DoubleValue(name, desc, min, max, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBCD.gridy = row;
          panel.add(new JLabel(desc), gA);
          panel.add(val.getTextField(), gBCD);
          row++;
      }
  
      public void addDoubleSlider(String name, String desc, double min, double max, double value)
      {
          DoubleValue val = new DoubleValue(name, desc, min, max, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBC.gridy = row;
          gD.gridy = row;
  
          panel.add(new JLabel(desc), gA);
          panel.add(val.getSlider(), gBC);
          panel.add(val.getLabel(), gD);
          row++;
      }
  
      public void addString(String name, String desc, String value)
      {
          StringValue val = new StringValue(name, desc, null, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBCD.gridy = row;
  
          panel.add(new JLabel(desc), gA);
          panel.add(val.getTextField(), gBCD);
          row++;
      }
  
      public void addChoice(String name, String desc, String values[], int value)
      {
          StringValue val = new StringValue(name, desc, values, values[value]);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBCD.gridy = row;
  
          panel.add(new JLabel(desc), gA);
          panel.add(val.getComboBox(), gBCD);
          row++;
      }
  
      public void addBoolean(String name, String desc, boolean value)
      {
          BooleanValue val = new BooleanValue(name, desc, value);
          parammap.put(name, val);
  
          gA.gridy = row;
          gBCD.gridy = row;
          panel.add(new JLabel(desc), gA);
          panel.add(val.getCheckBox(), gBCD);
          row++;
      }
  
      public void addButton(String name, String desc)
      {
          addButtons(name, desc);
      }
  
      public void addButtons(Object... args)
      {
          JPanel p = new JPanel();
          p.setLayout(new GridLayout(1, args.length/2));
  
          for (int i = 0; i < args.length/2; i++)
  	    {
              String name = (String) args[i*2];
              String desc = (String) args[i*2+1];
  
              JButton button = new JButton(desc);
              button.addActionListener(new ActionNotifier(name));
  
              p.add(button);
  	    }
  
          gABCD.gridy = row;
          panel.add(p, gABCD);
          row++;
      }
  
      public void addCheckBoxes(Object... args)
      {
          JPanel p = new JPanel();
          p.setLayout(new GridLayout(1, args.length/3));
  
          for (int i = 0; i < args.length/3; i++)
  	    {
              String name = (String) args[i*3+0];
              String desc = (String) args[i*3+1];
              boolean value = (Boolean) args[i*3+2];
  
              BooleanValue bv = new BooleanValue(name, desc, value);
              parammap.put(name, bv);
  
              p.add(bv.getCheckBox());
  	    }
  
          gABCD.gridy = row;
          panel.add(p, gABCD);
          row++;
      }
  
      public double gd(String name)
      {
          PValue p = parammap.get(name);
          assert(p!=null);
          assert(p instanceof DoubleValue);
  
          return ((DoubleValue) p).getDoubleValue();
      }
  
      public void sd(String name, double v)
      {
          PValue p = parammap.get(name);
          assert(p!=null);
          assert(p instanceof DoubleValue);
  
          ((DoubleValue) p).setDoubleValue(v);
      }
  
      public int gi(String name)
      {
  