4

指定された最小値指定された最大Double値の間のすべての可能な値を取ることができる JSpinner を作成したいと思います。

また、JSpinner は特定の値の代わりにテキストを表示できる必要があります。JSpinner が -1 から 10 までの値を取ることができるとしましょう。 -1 の代わりに "Auto" などのテキストを表示したいと思います。

交換通常の Jspinner : わかります方法 私たちが見ることができるJSpinner

ここに私が書いたモデルがありますが、テキストがDouble.

public class SpinnerSpecialModel
        extends AbstractSpinnerModel implements SpinnerMinMaxModel {

  public static final double DEFAULT_MINIMUM = 0.0;
  public static final double DEFAULT_MAXIMUM = Double.POSITIVE_INFINITY;
  public static final double DEFAULT_STEP = 1.0;
  public static final double DEFAULT_VALUE = 1.0;
  public static final double DEFAULT_SPECIAL_NUMBER = -1.0;
  public static final String DEFAULT_SPECIAL_TEXT = "Auto";

  private double maximum;
  private double minimum;
  private double stepSize;
  private double currentNumber;
  private double specialNumber;
  private String specialText;

  private Object m_Value;

  public SpinnerSpecialModel(double max, double min, double step, double num, 
        double specialNum, String specialTxt) {
    maximum = max;
    minimum = min;
    stepSize = step;
    currentNumber = num;
    specialNumber = specialNum;
    specialText = specialTxt;
    setAccurateValue(num);
  }

  public SpinnerSpecialModel(double specialNum, String specialTxt) {
    this(DEFAULT_MAXIMUM, DEFAULT_MINIMUM,
        DEFAULT_STEP, DEFAULT_VALUE, specialNum, specialTxt);
  }

  public SpinnerSpecialModel() {
    this(DEFAULT_SPECIAL_NUMBER, DEFAULT_SPECIAL_TEXT);
  }

  @Override
  public Object getValue() {
    if (currentNumber == specialNumber) {
      m_Value = specialText;
    }
    else {
      m_Value = currentNumber;
    }
    return m_Value;
  }

  @Override
  public void setValue(Object value) {
    setAccurateValue(value);
  }

  private void setAccurateValue(Object value) {
    if (value instanceof Double) {
      double doubleValue = (Double) value;
      if (doubleValue != currentNumber) {
        if (doubleValue == specialNumber) {
          currentNumber = specialNumber;
          m_Value = specialText;
        }
        else if (doubleValue > maximum) {
          currentNumber = maximum;
          m_Value = maximum;
        }
        else if (doubleValue < minimum) {
          currentNumber = maximum;
          m_Value = minimum;
        }
        else {
          currentNumber = doubleValue;
          m_Value = doubleValue;
        }
        fireStateChanged();
      }
    }

    if (value instanceof String) {
      String stringValue = (String) value;
      if (stringValue.equals(specialText)) {
        this.currentNumber = specialNumber;
        this.m_Value = specialText;
        fireStateChanged();
      }
    }
  }

  @Override
  public Object getNextValue() {
    return getNewValue(+1);
  }

  @Override
  public Object getPreviousValue() {
    return getNewValue(-1);
  }

  /**
   * 
   * @param direction
   * @return 
   */
  private Object getNewValue(int direction) {
    double newValue = currentNumber + direction * stepSize;
    setAccurateValue(newValue);
    return m_Value;
  }

  @Override
  public double getMaximum() {
    return maximum;
  }

  @Override
  public double getMinimum() {
    return minimum;
  }

  @Override
  public double getStepSize() {
    return stepSize;
  }

  @Override
  public void setMaximum(double max) {
    maximum = max;
  }

  @Override
  public void setMinimum(double min) {
    minimum = min;
  }

  @Override
  public void setStepSize(double step) {
    stepSize = step;
  }
}
4

2 に答える 2

1

これを行うための最善かつ適切な方法は、モデルを記述するだけの単純なものではありませんが、それほど複雑ではありません。真の MVC スピナーを使用するには、実際には anEditorと aを記述する必要があります。Formatter

  • 拡張するクラスJSpinner: SpecialValuesSpinner.
  • SpinnerModel を実装するクラス:SpecialValuesSpinnerModel
  • 拡張DefaultEditorおよび実装するクラスDocumentListener:SpecialValuesSpinnerEditor
  • 拡張するクラスNumberFormatter:SpecialValuesSpinnerFormatter

すべてのクラスのコードを紹介するつもりはありませんが、基本的に各クラスで行う必要があるのは次のとおりです。

SpecialValuesSpinner :

public class SpecialValuesSpinner() extends SpinnerNumberModel {
    // in your constructor do this
    setModel(new SpecialValuesSpinnerModel(YOUR_SPECIAL_VALUES);
    setEditor(new SpecialValuesSpinnerEditor());
}

SpecialValuesSpinnerModel :

public class SpinnerSpecialValuesModel() extends JSpinner {
    // in this class you handle the fact that now, you have an
    // interval of values and a list of special values that are allowed.
    // here is what I did :
    @Override
    public Object getNextValue() {
        return incrValue(+1);
    }

    @Override
    public Object getPreviousValue() {
        return incrValue(-1);
    }

    private Object incrValue(int dir) {
        // NB : BigDecimal here because this is what I used,
        // but use what you want in your model
        BigDecimal result = null;
        BigDecimal numberBD = new BigDecimal(getNumber().toString());
        BigDecimal stepSizeBD = new BigDecimal(getStepSize().toString());
        BigDecimal dirBD = new BigDecimal(dir);
        BigDecimal nextValue = numberBD.add(stepSizeBD.multiply(dirBD));

        TreeSet<BigDecimal> currentAllowedValues = new TreeSet<BigDecimal>();
        currentAllowedValues.addAll(m_SpecialValues);
        if (getMaximum() != null) {
          currentAllowedValues.add((BigDecimal) getMaximum());
        }
        if (getMinimum() != null) {
          currentAllowedValues.add((BigDecimal) getMinimum());
        }
        if (isIncludedInBounds(nextValue)) {
          currentAllowedValues.add(nextValue);
        }

        if (dir > 0) {
          try {
            result = currentAllowedValues.higher(numberBD);
          }
          catch (NoSuchElementException e) {}
        }
        else if (dir < 0) {
          try {
            result = currentAllowedValues.lower(numberBD);
          }
          catch (NoSuchElementException e) {}
        }
        return result;
    }
}

SpecialValuesSpinnerEditor では、Document Listener を使用してオートコンプリートを行います (SO で検索するだけで簡単に実行できます)。

public class SpecialValuesSpinnerEditor extends DefaultEditor implements DocumentListener {

    // You have to do in your contructor
    SpecialValuesSpinnerFormatter formatter = 
        new SpecialValuesSpinnerFormatter (spinner.getSpecialValues(), format);
    getTextField().setFormatterFactory(new DefaultFormatterFactory(formatter));
}

そして今、最も重要なのは、ユーザー入力 (文字列) と数値の間の変換を行い、モデルの表示を処理する Formatter です。

public class SpecialValuesSpinnerFormatter extends NumberFormatter {
    // Just override the methos StringToValue and ValueToString.
    // You can check here if the value is special
    // i.e you must display its special text instead. e.g. : "Auto" instead of -1
}
于 2013-06-13T15:17:05.043 に答える
1

独自のものを実装し、それをコンストラクターSpinnerModelへの引数として提供することで、それを達成できると思います。JSpinner

于 2013-03-28T14:22:20.657 に答える