JSpinner - 単純なシーケンス・コンテナ

このドキュメントでは、新しいSwingコンポーネントであるJSpinnerについて説明します。

もっとも多く作成の要求があったSwingコンポーネントの1つに、スピナーがあります。これは、ユーザーが順序付けられた集合から数値またはオブジェクト値を選択できるようにする単一行の入力フィールドです。スピナーには通常、選択可能な値を段階的に表示するための一組の小さな矢印型ボタンが提供され、上矢印キーと下矢印キーでも値を循環して表示できます。ユーザーがスピナーに直接(有効な)値を入力することもできます。コンボボックスは類似の機能を提供しますが、重要なデータを覆い隠してしまうドロップ・ダウン・リストを必要としないため、スピナーの方が好まれる場合があります。

この変更に関連するバグ追跡レポート: 4290529

スピナーのカタログ

スピナーは、最新のGUIで一般的なものです。次に、いくつかの一般的なルック・アンド・フィールとOpenWindowsからの例を示します。

Windowsスピナー CDE/Motifスピナー JLFスピナー Mac Aquaスピナー 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と似ており、両方とも値のシーケンスを表現しますが、重要な相違点がいくつかあります。

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プロパティを初期化することに加えて、これらのコンストラクタは、SpinnerModelvalueを表示し、これを変更するのに使用できるエディタ・コンポーネントを作成します。デフォルトでは、このためにprotected JSpinner.createEditorメソッドが使用され、このメソッドが、モデルを表示するために構成されたJFormattedTextFieldを作成します。

スピナーの現在値を検出または初期化するには、モデルのvalueプロパティを使用するか、または、モデルに委譲されたばかりの、便利なJSpinner valueプロパティを使用することができます。たとえば、上の例で構成されたスピナーを使用すると、次の2つの文は同等です。

    String selectedDay = spinner.getModel().getValue().toString();
    String selectedDay = spinner.getValue().toString();

スピナーの値の設定は似ています。モデルがサポートしないオブジェクトにSpinnerModelの値を設定しようとすると、IllegalArgumentExceptionがスローされます。

日付と数値は、スピナーのコンポーネントにもっとも一般的に適用される2つです。これらの型のスピナー化を単純にするために、SpinnerDateModelSpinnerNumberModelの、2つのSpinnerModel実装クラスが追加されました。

SpinnerDateModel

スピナーのもっとも一般的な使用法の1つが、編集可能な日付をコンパクトに提示することです。次に、ユーザーが完全にローカライズされた日付を入力できるJSpinnerの作成例を示します。

    SpinnerDateModel model = new SpinnerDateModel();
    JSpinner spinner = new JSpinner(model);
    Date value = model.getDate();

この例で、JSpinnerコンストラクタは、日付を編集するように構成されるJFormattedTextFieldエディタを作成し、ChangeListenerSpinnerDateModelに追加して、editorとモデルの同期を保ちます。

ここで、SpinnerDateModel APIを示します。startend、および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メソッドは、この定数に基づいて日付を前後に変更します。たとえば、stepSizeCalendar.DAY_OF_WEEKの場合、nextValueは現在のvalueの24時間後のDateを生成し、previousValueは24時間前のDateを生成します。

stepSizeの正当な値は次のとおりです。

デフォルトのSpinnerDateModel editorは、テキストのカーソル位置に基づいてstepSizeプロパティを調節します。たとえば、カーソルがエディタのmonthサブフィールドに移動した場合は、incrementSizeCalendar.DAY_OF_MONTHに変更されます。

SpinnerNumberModel

スピナーはしばしば、気温から株価までのあらゆる数値を表す、編集可能な整数および実数を提示するために使用されます。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エディタを作成し、ChangeListenerSpinnerNumberModelに追加して、editorとモデルの同期を保ちます。

ここで、SpinnerNumberModel APIについて簡単にまとめます。minimummaximum、および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と加算または減算する値を指定します。

スピナーAPIのサマリー

スピナーのサポートにあたって、次の6つのクラスと1つのインタフェース(SpinnerModel)がjavax.swingパッケージに追加されました。

また、SpinnerUIjavax.swing.plafパッケージに、BasicSpinnerUIjavax.swing.plaf.basicパッケージに追加されました。


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.