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

このドキュメントでは、書式付きテキスト・フィールドの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用のセッター/ゲッターがあり、必要に応じてDocumentFilterをサポートできるように、AbstractDocumentから派生しないDocumentのためのプロパティが設定されます)。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.replace(fb, offset, length, string, attr);
      }
   };

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

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

    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の公開されているstaticの内部クラス)のインスタンスに委譲します。この委譲によって、開発者がさまざまな状態の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の命名規則に準拠するように変更されました。


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