JSpinner
- 単純なシーケンス・コンテナこのドキュメントでは、新しいSwingコンポーネントであるJSpinnerについて説明します。
もっとも多く作成の要求があったSwingコンポーネントの1つに、スピナーがあります。これは、ユーザーが順序付けられた集合から数値またはオブジェクト値を選択できるようにする単一行の入力フィールドです。スピナーには通常、選択可能な値を段階的に表示するための一組の小さな矢印型ボタンが提供され、上矢印キーと下矢印キーでも値を循環して表示できます。ユーザーがスピナーに直接(有効な)値を入力することもできます。コンボボックスは類似の機能を提供しますが、重要なデータを覆い隠してしまうドロップ・ダウン・リストを必要としないため、スピナーの方が好まれる場合があります。
この変更に関連するバグ追跡レポート: 4290529。
スピナーは、最新のGUIで一般的なものです。次に、いくつかの一般的なルック・アンド・フィールとOpenWindowsからの例を示します。
Windows | CDE/Motif | JLF | Mac Aqua | OpenWindows |
これらのスピナーはすべて、非常に単純な動作を行います。スピナーにフォーカスがあるときに矢印ボタンをクリックすると、フィールドの値が変わります。キーボードの上矢印キーと下矢印キーでも同じ結果になります。アプリケーションによっては、スピナーの値が上限または下限に達すると、上矢印または下矢印ボタンが無効になったり、その値が反対の極限値にリセットされたりします。
JSpinner
, SpinnerModel
, SpinnerListModel
JSpinner
クラスは、3つの子を管理する単純なSwingコンテナです。子とは、2つの矢印ボタンと、スピナーの値を表示するためのエディタと呼ばれる1つのコンポーネントです。スピナーに表示される値は、SpinnerModel
と呼ばれるオブジェクトのシーケンスから構成されるモデルによってカプセル化されます。
public interface SpinnerModel { Object getValue(); void setValue(Object); Object getNextValue(); Object getPreviousValue(); void addChangeListener(ChangeListener x); void removeChangeListener(ChangeListener x);}
SpinnerModel
インタフェースは、ListModel
と似ており、両方とも値のシーケンスを表現しますが、重要な相違点がいくつかあります。
size
メソッドからシーケンスの長さは返されない。ListModels
シーケンスの要素とは異なる。この違いが、JList
とJSpinner
の役割の違いを反映している。前者はリストからの1つ以上の項目の選択を単純化するために設計されたのに対し、後者は単一の値を直接入力するために設計された。JSpinner
とそのモデルとの関係は単純です。エディタ・コンポーネントはChangeListener
経由でモデルをモニターし、SpinnerModel.getValue()
によって返されたオブジェクトを常に表示します。上向きおよび下向きの矢印ボタンは、それぞれsetValue(getNextValue())
またはsetValue(getPreviousValue())
を呼び出すことで値を更新します。シーケンスの最後または先頭に達したときにgetNextValue
およびgetPreviousValue
メソッドはnull
を返すので、矢印ボタンのアクションでは、モデルの値を更新する前にnull
をチェックする必要があります。エディタがある種の書込み可能なフィールドの場合は、モデルに定義された制約を尊重すること、または無効な値に対してsetValue
によってスローされたIllegalArgumentException
を処理することが、エディタの役割になります。
SpinnerListModel
では、java.util.List
およびオブジェクト配列という、2つの一般的な可変のシーケンス型がサポートされます。デフォルトのロケールでユーザーが曜日を選択できるようにするJSpinner
を作成する例は、次のようになります。
String[] days = new DateFormatSymbols().getWeekdays(); SpinnerModel model = new SpinnerListModel(days); JSpinner spinner = new JSpinner(model);
スピナーのmodel
プロパティを初期化することに加えて、これらのコンストラクタは、SpinnerModel
のvalue
を表示し、これを変更するのに使用できるエディタ・コンポーネントを作成します。デフォルトでは、このためにprotected JSpinner.createEditor
メソッドが使用され、このメソッドが、モデルを表示するために構成されたJFormattedTextField
を作成します。
スピナーの現在値を検出または初期化するには、モデルのvalue
プロパティを使用するか、または、モデルに委譲されたばかりの、便利なJSpinner
value
プロパティを使用することができます。たとえば、上の例で構成されたスピナーを使用すると、次の2つの文は同等です。
String selectedDay = spinner.getModel().getValue().toString(); String selectedDay = spinner.getValue().toString();
スピナーの値の設定は似ています。モデルがサポートしないオブジェクトにSpinnerModel
の値を設定しようとすると、IllegalArgumentException
がスローされます。
日付と数値は、スピナーのコンポーネントにもっとも一般的に適用される2つです。これらの型のスピナー化を単純にするために、SpinnerDateModel
とSpinnerNumberModel
の、2つのSpinnerModel
実装クラスが追加されました。
SpinnerDateModel
スピナーのもっとも一般的な使用法の1つが、編集可能な日付をコンパクトに提示することです。次に、ユーザーが完全にローカライズされた日付を入力できるJSpinner
の作成例を示します。
SpinnerDateModel model = new SpinnerDateModel(); JSpinner spinner = new JSpinner(model); Date value = model.getDate();
この例で、JSpinner
コンストラクタは、日付を編集するように構成されるJFormattedTextField
エディタを作成し、ChangeListener
をSpinnerDateModel
に追加して、editor
とモデルの同期を保ちます。
ここで、SpinnerDateModel
APIを示します。start
、end
、およびstepSize
の3つの新しい読み取り/書込み両用プロパティと、Date
にキャストするvalueを返す読取り専用のdate
プロパティが追加されました。
public class SpinnerDateModel extends AbstractSpinnerModel { public SpinnerDateModel(Date value, Comparable start, Comparable end, int stepSize) public SpinnerDateModel() public void setStart(Comparable start) public Comparable getStart() public void setEnd(Comparable end) public Comparable getEnd() public Object getNextValue() public Object getPreviousValue() public Date getDate() public Object getValue() public void setValue(Object value)}
上限または下限のないことを示すために、startDate
プロパティおよびendDate
プロパティをnull
にすることができます。引数を指定しないSpinnerDateModel
コンストラクタの場合は、開始日と終了日の両方をnull
に初期化し、モデルの最初の日付は現在の日付です。
stepSize
プロパティの値は、Calendar
内のフィールドを指定するjava.util.Calendar
定数のいずれかである必要があります。getNextValue
メソッドとgetPreviousValue
メソッドは、この定数に基づいて日付を前後に変更します。たとえば、stepSize
がCalendar.DAY_OF_WEEK
の場合、nextValue
は現在のvalue
の24時間後のDate
を生成し、previousValue
は24時間前のDate
を生成します。
stepSize
の正当な値は次のとおりです。
Calendar.ERA
Calendar.YEAR
Calendar.MONTH
Calendar.WEEK_OF_YEAR
Calendar.WEEK_OF_MONTH
Calendar.DAY_OF_MONTH
Calendar.DAY_OF_YEAR
Calendar.DAY_OF_WEEK
Calendar.DAY_OF_WEEK_IN_MONTH
Calendar.AM_PM
Calendar.HOUR
Calendar.HOUR_OF_DAY
Calendar.MINUTE
Calendar.SECOND
Calendar.MILLISECOND
デフォルトのSpinnerDateModel
editor
は、テキストのカーソル位置に基づいてstepSize
プロパティを調節します。たとえば、カーソルがエディタのmonthサブフィールドに移動した場合は、incrementSize
がCalendar.DAY_OF_MONTH
に変更されます。
スピナーはしばしば、気温から株価までのあらゆる数値を表す、編集可能な整数および実数を提示するために使用されます。SpinnerNumberModel
では、Byte
からDouble
までの基本的なすべてのJavaのNumber
型を基本的にサポートします。
初期値を500.0にして、0.0から1000.0の間で1/8の実数の倍数をユーザーが選択できるようにするスピナーを作成するには、次のようにコーディングします。
SpinnerNumberModel model = new SpinnerNumberModel(500.0, 0.0, 1000.0, 0.625); JSpinner spinner = new JSpinner(model); double value = model.getNumber().doubleValue();
この例で、JSpinner
コンストラクタは、実数を編集するように構成されるJFormattedTextField
エディタを作成し、ChangeListener
をSpinnerNumberModel
に追加して、editor
とモデルの同期を保ちます。
ここで、SpinnerNumberModel
APIについて簡単にまとめます。minimum
、maximum
、およびstepSize
の3つの新しい読み取り/書込み両用プロパティと、Number
にキャストするvalue
を返す読取り専用のnumber
プロパティが追加されました。
public class SpinnerNumberModel extends AbstractSpinnerModel { public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum, Number stepSize) public SpinnerNumberModel(int value, int minimum, int maximum, int stepSize) public SpinnerNumberModel(double value, double minimum, double maximum, double stepSize) public SpinnerNumberModel() public void setMinimum(Comparable minimum) public Comparable getMinimum() public void setMaximum(Comparable maximum) public Comparable getMaximum() public void setStepSize(Number stepSize) public Number getStepSize() public Object getNextValue() public Object getPreviousValue() public Number getNumber() public Object getValue() public void setValue(Object value)}
SpinnerDateModel
に関しては、minimum
およびmaximum
プロパティが、それより大きな値または小さな値がないことを示すために、null
になる可能性もあります。stepSize
プロパティには、nextValue
またはpreviousValue
を計算するためにvalue
と加算または減算する値を指定します。
スピナーのサポートにあたって、次の6つのクラスと1つのインタフェース(SpinnerModel
)がjavax.swing
パッケージに追加されました。
また、SpinnerUI
がjavax.swing.plaf
パッケージに、BasicSpinnerUI
がjavax.swing.plaf.basic
パッケージに追加されました。