書式付きテキストフィールド

このドキュメントでは、書式付きテキストフィールドの Swing での実装の概略を説明します。 書式付きテキストフィールドによって、開発者は、テキストコンポーネントに入力できる正当な文字セットを指定できるようになります。 このドキュメントは、以下の節で構成されています。

JFormattedTextField の使用

JFormattedTextField によって、日付、数値、文字列および任意のオブジェクトの書式を設定することができます。 JFormattedTextField は、java.text.Format クラスに基づいて、日付と数値に書式を設定します。 現在のロケール固有の書式で日付を入力するための JFormattedTextField を作成するには、次のようにします。

    new JFormattedTextField(new Date());

特定の書式で日付を表示することが必要な場合は、 SimpleDateFormat コンストラクタの 1 つを使用できます。

    new JFormattedTextField(new SimpleDateFormat("MM/dd/yy"));

数値は、 java.text.NumberFormat のインスタンスによって処理されます。 以下に、数値を編集する JFormattedTextField を作成する方法をいくつか示します。

   new JFormattedTextField(new Number(1000));
   new JFormattedTextField(new DecimalFormat("#,###"));
   new JFormattedTextField(new DecimalFormat("0.###E0"));

JFormattedTextField は、マスクが指定された文字列の編集もサポートします。このマスクで、指定した文字位置に置く有効な文字を指定します。 米国の電話番号を編集する JFormattedTextField を作成するには、次のコードを使用することができます。

   new JFormattedTextField(new MaskFormatter("(###) ###-####"));

JFormattedTextField の作用

JFormattedTextField 自体は、そのスーパークラスである JTextField の API のほかは、最小限の API を公開します。 もっとも単純に説明すれば、JFormattedTextField は、JTextField に追加の Object 型の値のプロパティ、および書式を設定するオブジェクト ( AbstractFormatter のインスタンス) が付いたものとみなすことができます。

値のプロパティが Object 型であるため、開発者にとっては、JFormattedTextField がどのように構成されたかに基づいて戻り値の型をキャストする必要があります。 以下に、日付と JFormattedTextField の使用法についての典型的なシナリオを示します。

  JFormattedTextField ftf = new JFormattedTextField();
  ftf.setValue(new Date());
  ...
  Date date = (Date)ftf.getValue();

数値を編集する典型的なセッションは、次のようになります。

  JFormattedTextField ftf = new JFormattedTextField();
  ftf.setValue(new Integer(1000));
  ...
  int intValue = ((Number)ftf.getValue()).intValue();

フィルタリング入力

テキストコンポーネントにデータを入力するには、以前は Document のサブクラスを作成することが必要でした。 この作業は、単純で一般的な使用法としては、負荷が多い操作でした。 この作業を簡略化するために、Document にプラグインできる DocumentFilter クラスが作成されました。Document は、変更されなかったインタフェースです。代わりに、現在は AbstractDocumentDocumentFilter 用のセッタ/ゲッタがあり、AbstractDocument から派生しなかった Document のためにプロパティが設定されるので、DocumentFilter をサポートできます。 DocumentFilter 付きの Document がコンテンツを削除または挿入するようにメッセージを受け取ると、DocumentDocumentFilter 上でメッセージに応じたメソッドを呼び出します。 操作を進行させる必要がある場合にコールバックを呼び出すことが、DocumentFilter の役割になります。 この方法で、DocumentFilterDocument を変更できる方法についての全体的な制御権を持ちます。 DocumentFilter は、次のようにして定義されます。

  public void remove(FilterBypass fb, int offset, int length) throws BadLocationException;
  public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException;
  public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException;

DocumentFilterremove または insertString メソッドの内部から Document を変更したい場合は、super 実装を呼び出すか、FilterBypass 上でそのメソッドを呼び出す必要があります。 super または FilterBypass 上でメソッドを呼び出すと、フィルタを迂回する方法が提供されるので、呼び出し側はスタック再帰から抜け出せなくなることがありません。 DocumentFilter には、FilterBypass 上で 1 つだけメソッドを呼び戻すという制限はありません。 FilterBypass によって開示されたどのメソッドでも呼び出すことができ、DocumentFilter のメソッドの 1 つの適用範囲内で必要なだけ何回でも呼び出すことができます。 FilterBypass は、次のようにして定義されます。

  public abstract Document getDocument();
  public abstract void remove(int offset, int length) throws BadLocationException;
  public abstract void insertString(int offset, String string, AttributeSet attr) throws BadLocationException;
  public abstract void replace(int offset, int length, String string, AttributeSet attr) throws BadLocationException;

次の例で、英小文字を英大文字にマッピングする DocumentFilter を作成する方法を示します。

   DocumentFilter upperDF = new DocumentFilter() {
      public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
          super.insertString(fb, offset, string.toUpperCase(), attr);
      }

      public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
          if (string != null) {
              string = text.toUpperCase();
          }
          super.insertString(fb, offset, string, attr);
      }
   };

フィルタリングナビゲーション

DocumentFilter と同様に、新規クラスの NavigationFilter によって、選択範囲を置き換えることが可能な場所でフィルタリングを実行できるようになります。 NavigationFilter は、ある位置から選択範囲を設定する次の位置を決定するナビゲーション操作 (左、右、中央など) によって呼び出されます。 NavigationFilter JTextComponent のプロパティであり、次のように定義されています。

    public void setDot(FilterBypass fb, int dot, Position.Bias bias);
    public void moveDot(FilterBypass fb, int dot, Position.Bias bias);
    public int getNextVisualPositionFrom(JTextComponent text, int pos, Position.Bias bias, int direction, Position.Bias[] biasRet) throws BadLocationException;

getNextVisualPositionFromView 内に定義されており、一貫性を保つために、NavigationFilter 内のメソッドと同じ名前が付けられています。

DocumentFilter と同様に、NavigationFilter は、実際の変更を処理するために呼び出される FilterBypass に渡されます。 NavigationFilter.FilterBypass は、次のように定義されています。

    public abstract Caret getCaret();
    public abstract void setDot(int dot, Position.Bias bias);
    public abstract void moveDot(int dot, Position.Bias bias);

JFormattedTextField.AbstractFormatter

前述したように、AbstractFormatter のインスタンスは特定の Object 値の書式を設定するために使用されます。 AbstractFormatter は、DocumentFilter を定義して編集ポリシーを指定したり、NavigationFilter を定義してナビゲーションポリシーを指定したりすることもできます。 AbstractFormatter は、次のように定義されています。

    public void install(JFormattedTextField ftf);
    public void uninstall();
    public abstract Object stringToValue(String text) throws ParseException;
    public abstract String valueToString(Object value) throws ParseException;
    protected JFormattedTextField getFormattedTextField();
    protected void setEditValid(boolean valid);
    protected void invalidEdit();
    protected Action[] getActions();
    protected DocumentFilter getDocumentFilter();
    protected NavigationFilter getNavigationFilter();

JFormattedTextFieldAbstractFormatter を使用する準備ができると、install を呼び出します。 AbstractFormatter.install は、次の作業を実行します。

  1. JFormattedTextField のテキストを valueToString の戻り値に設定する (ParseException がスローされた場合は空の文字列が使用され、setEditValid(false) が呼び出される)。
  2. getDocumentFilter から返された DocumentFilterJFormattedTextFieldDocument にインストールする。
  3. getNavigationFilter から返された NavigationFilterJFormattedTextField にインストールする。
  4. getActions から返された ActionJFormattedTextFieldActionMap にインストールする。

サブクラスで DocumentFilter および NavigationFilter の範囲を超えた追加の Listener をインストールする必要がある場合は、サブクラスは install をオーバーライドするだけか、または最初の位置にキャレットを配置することがあります。

ある種の AbstractFormatter では、JFormattedTextField が編集中に無効な値を含むことが許容されます。 JFormattedTextField で無効な値を含んでいることを示すことができるように、AbstractFormatter は、ユーザが無効な値を入力したときに setEditValid(false) を呼び出します。有効な値が入力されると、 setEditValid(true) が呼び出されます。

JFormattedTextFieldAbstractFormatter で処理される場合は、uninstall を呼び出します。 uninstall によって、以前インストールされた Listener が削除されます。

JFormattedTextField.AbstractFormatterFactory

JFormattedTextField は、AbstractFormatter の作成を AbstractFormatterFactory (JFormattedTextField の公開されている静的な内部クラス) のインスタンスに委譲します。 この委譲によって、開発者がさまざまな状態の JFormattedTextField に多様なフォーマッタを提供することが簡単になります。 たとえば、現在の値が null の場合は特殊な AbstractFormatter、または編集中にはあるフォーマッタ、表示中には別のフォーマッタを提供することができます。 AbstractFormatterFactory は、次のように定義されています。

    public abstract AbstractFormatter getFormatter(JFormattedTextField ftf);

開発者が AbstractFormatterFactory を供給しなかった場合は、値の Class に基づいたフォーマッタが作成されます。

DefaultFormatter

DefaultFormatterJFormattedTextField.AbstractFormatter を拡張します。これは、提供されたフォーマッタ実装のすべてに対応するスーパークラスです。 DefaultFormattertoString を使用して Object の書式を設定し、String をとるコンストラクタを使用して Object を作成します。 DefaultFormatter では、多数の構成オプションを使用できます。

オプション

説明

CommitsOnValidEdit 編集が JFormattedTextField に公開されて戻される時点を決定する。 true の場合は、各編集が成功した後に JFormattedTextField 上で commitEdit が呼び出される。そうでない場合は、Return キーが押されたときにだけ commitEdit が呼び出される。
OverwriteMode 文字を挿入するときの動作を構成する。 overwriteModetrue の場合 (デフォルト) は、新しい文字が挿入されたときにモデル内の既存の文字がオーバーライドされる。
AllowsInvalid 編集中の値が無効であっても許容されるかどうかを決定する。 確定が試行されるまでユーザが無効な値を入力できるようにしておくと、便利な場合が多い。

AbstractFormatter の実装

次の表に、使用されることを目的として提供する AbstractFormatter の実装を示します。

AbstractFormatter

オブジェクトの型

説明

DefaultFormatter オブジェクト valueToStringObject.toString() を使用し、stringToValue が文字列をとる単一引数のコンストラクタを使用する。
MaskFormatter 文字列 動作は、適切な値 (###-#### など) を指定する文字単位のマスクで示される。
InternationalFormatter オブジェクト java.text.Format のインスタンスを使用して、valueToString および stringToValue を処理する。
NumberFormatter 数値 InternationalFormatter から派生した NumberFormat のインスタンスを使用して、書式を設定する。
DateFormatter 日付 InternationalFormatter から派生した DateFormat のインスタンスを使用して、書式を設定する。

java.text.Format の変更

Swing では、java.text パッケージ内の Format クラスの拡張使用が可能な、書式付きの日付と数値がサポートされています。 以前の API では、次のような問題点がありました。

これらの問題点は、以下のメソッドを java.text.Format に追加することで、大幅に対処されました。

    public AttributedCharacterIterator formatToCharacterIterator(Object obj);

Format クラスでは、サポートする定数のために型保証された列挙を使用しています。

JavaDoc

新しいクラス

以下のクラスが 1.4 リリースでの新規クラスです。

Java の命名規則に準拠するよう定数の名前が変更された

この変更に関連するバグレポート: 4468474.

次の定数の名前は、Java の命名規則に準拠するように変更されました。