Summary

JSpinnerに表示する数値を0.5単位で切り捨て、または四捨五入するよう設定します。

Source Code Examples

private static DefaultFormatter makeDownFormatter() {
  return new DefaultFormatter() {
    @Override public Object stringToValue(String text) {
      return roundToDown(new BigDecimal(text)).doubleValue();
   }

   @Override public String valueToString(Object value) {
      return roundToDown(BigDecimal.valueOf((Double) value)).toString();
    }
  };
}

private static BigDecimal roundToDown(BigDecimal value) {
  return value.multiply(BigDecimal.valueOf(2))
      .setScale(0, RoundingMode.DOWN)
      .multiply(BigDecimal.valueOf(.5));
}
View in GitHub: Java, Kotlin

Explanation

  • Default, stepSize: 0.5
    • デフォルトのSpinnerNumberModelにステップサイズを0.5として使用
    • 矢印ボタンでJSpinnerの数値を変更すると0.5単位で増減するが、たとえば直接8.85を入力しても0.5単位の端数処理などは適用されない
  • Override SpinnerNumberModel
    • SpinnerNumberModel#setValue(...)メソッドをオーバーライドして値を0.5単位で切り捨て
    • コンストラクタで初回の現在値を設定する場合はSpinnerNumberModel#setValue(...)が使用されないので、super(roundDownToHalf(value), min, max, step);のように切り捨てを実行している
class RoundToHalfSpinnerModel extends SpinnerNumberModel {
  protected RoundToHalfSpinnerModel(
      double value, double min, double max, double step) {
    super(roundDownToHalf(value), min, max, step);
  }

  @Override public void setValue(Object value) {
    if (value instanceof Double) {
      Double v = roundDownToHalf((Double) value);
      if (!v.equals(getValue())) {
        super.setValue(v);
        fireStateChanged();
      }
    } else {
      throw new IllegalArgumentException("illegal value");
    }
  }

  private static double roundDownToHalf(Double value) {
    return BigDecimal.valueOf(value)
        .multiply(BigDecimal.valueOf(2))
        .setScale(0, RoundingMode.DOWN)
        .multiply(BigDecimal.valueOf(.5))
        .doubleValue();
  }
}
  • Round down to half Formatter
    • JSpinner.DefaultEditorからJFormattedTextFieldを取得して、0.5単位で切り捨てを実行するDefaultFormatterFactoryを設定
    • 0.5単位の切り捨ては、BigDecimalの値を2倍したあとBigDecimal#setScale(0, RoundingMode.DOWN)で小数点以下を切り捨てし、0.5倍することで実行している
  • Round to half Formatter
    • JSpinner.DefaultEditorからJFormattedTextFieldを取得して、0.5単位で四捨五入をを実行するDefaultFormatterFactoryを設定
    • 0.5単位の四捨五入は、BigDecimalの値を2倍したあとBigDecimal#setScale(0, RoundingMode.HALF_UP)で小数点以下を四捨五入し、0.5倍することで実行している

Reference

Comment