/** Creates the JSlider for this object */
  private void createSlider() {
    int initSliderValue = modelViewTransform.modelToView(initialValue);
    if (initSliderValue < SLIDER_MIN || initSliderValue > SLIDER_MAX) {
      throw new RuntimeException(
          "Illegal slider value, min="
              + SLIDER_MIN
              + ", max="
              + SLIDER_MAX
              + ", value="
              + initSliderValue);
    }
    final JSlider slider =
        new JSlider(SwingConstants.HORIZONTAL, SLIDER_MIN, SLIDER_MAX, initSliderValue);

    slider.setPaintTicks(true);
    slider.setPaintLabels(true);
    slider.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            int sliderValue = slider.getValue();
            double modelValue = modelViewTransform.viewToModel(sliderValue);
            if (!settingSliderValue) {
              setValue(modelValue);
            }
          }
        });
    int dMinor = SLIDER_MAX / (numMinorTicks - 1);
    double modelDX = Math.abs(modelViewTransform.viewToModel(dMinor / 4));
    SliderKeyHandler skh = new SliderKeyHandler(modelDX);
    slider.addKeyListener(skh);
    this.slider = slider;
    relabelSlider();
  }
 public void setModelLabels(Hashtable modelLabels) {
   Hashtable viewLabels = new Hashtable();
   Set keys = modelLabels.keySet();
   Iterator it = keys.iterator();
   while (it.hasNext()) {
     Object o = (Object) it.next();
     Number modelValue = (Number) o;
     double v = modelValue.doubleValue();
     int viewValue = modelViewTransform.modelToView(v);
     viewLabels.put(new Integer(viewValue), modelLabels.get(o));
   }
   slider.setLabelTable(viewLabels);
 }
  public void setValue(final double value) {
    // bugfix: test for change of state was incomplete: comparing the new 'value' against the old
    // 'value' missed valid changes in the transform.
    if (slider.getValue() == modelViewTransform.modelToView(value) && this.value == value) {
      return;
    }
    if (value >= min && value <= max) {
      String string = textFieldFormat.format(value);
      double newValue = value;
      try {

        newValue = textFieldFormat.parse(string).doubleValue();
        //                System.out.println( "value="+value+", string = " + string +",
        // newValue="+newValue);
      } catch (ParseException e) {
        e.printStackTrace();
      }
      //            string = string.replace( ',', '.' );
      //            double newValue = Double.parseDouble( string );
      if (slider.getValue() == modelViewTransform.modelToView(value) && this.value == newValue) {
        return;
      }

      this.value = newValue;
      textField.setText(string);
      int sliderValue = modelViewTransform.modelToView(value);
      if (sliderValue != slider.getValue()) {
        settingSliderValue = true; // disable recursive calls to this method
        slider.setValue(sliderValue); // this recursively changes values
        settingSliderValue = false;
        slider.revalidate();
        slider.repaint();
      }
      fireStateChanged();
    }
  }
  /**
   * Computes the numbers that appear directly below the slider, formats them, and adds them as
   * labels to the slider. Also lays out the tick marks
   */
  private void relabelSlider() {
    int dMajor = SLIDER_MAX / (numMajorTicks - 1);
    int dMinor = SLIDER_MAX / (numMinorTicks - 1);
    Font labelFont = new PhetFont(0, 10);
    Hashtable table = new Hashtable();
    for (int value = 0; value <= SLIDER_MAX; value += dMajor) {
      double modelValue = modelViewTransform.viewToModel(value);
      JLabel label = new JLabel(sliderLabelFormat.format(modelValue));
      label.setFont(labelFont);
      table.put(new Integer(value), label);
    }
    slider.setLabelTable(table);

    slider.setMajorTickSpacing(dMajor);
    slider.setMinorTickSpacing(dMinor);
  }