モジュール java.desktop
パッケージ javax.swing.text

インタフェースDocument

既知のすべてのサブインタフェース:
StyledDocument
既知のすべての実装クラス:
AbstractDocument, DefaultStyledDocument, HTMLDocument, PlainDocument

public interface Document

Documentはswingテキスト・コンポーネントのモデルとなるテキストのコンテナです。 このインタフェースのめざすところはプレーン・テキストのテキスト・フィールドのように非常にシンプルなものからHTMLまたはXMLのように複雑なものにまで対応できるようにスケーリングすることです。

Content

もっともシンプルなレベルでは、テキストは線状に伸びる一連の文字として形成されます。 国際化に備えてSwingテキスト・モデルはunicode文字を使用します。 通常、テキスト・コンポーネントに表示される文字シーケンスはコンポーネントのコンテンツと呼ばれます。

シーケンス内の場所を参照するために2文字間の位置座標を使用します。 下の図に示すように、テキスト・ドキュメント内の場所は位置として、またはオフセットとして示すことができます。 この位置はゼロから始まります。

次の文は、この図について説明しています。

たとえば、前の図のようにドキュメントのコンテンツが「The quick brown fox」というシーケンスの場合、「The」の前の場所は0で、「The」の後とそれに続く空白の間の場所は3となります。 「The」というシーケンスの全文字シーケンスを範囲と呼びます。

次のメソッドでコンテンツを構成する文字データへアクセスできます。

構造

テキストが単調なコンテンツとして表されることはほとんどありません。 むしろ、通常、テキストはコンテンツと関連した構造になっています。 正確にどの構造がモデルになっているかは特定のDocument実装により異なります。 単純なテキスト・フィールドのように構造がないようなシンプルなものもあれば、下の図のようなものもあります。

図は、Book、Chapter、Paragraphの順に示しています。

構造単位、すなわちツリーのノードはElementインタフェースで表せます。 各Elementは属性のセットによりタグを付けることができます。 こういう名前と値のペアの属性はAttributeSetインタフェースで定義されます。

次のメソッドでドキュメント構造へアクセスできます。

Mutations

すべてのドキュメントは簡単なテキストの追加および削除ができる必要があります。 通常、テキストはキーボードまたはマウスのジェスチャで挿入、削除ができます。 挿入、削除をした結果ドキュメント構造にどういう影響があるかはすべてドキュメントの実装によります。

次のメソッドはドキュメント・コンテンツの変化に関係付けられています。

Notification

Documentに変更が生じた場合は関係者に通知する必要があります。 変更通知はJavaBeansに指定されているイベント・モデルのガイドラインに準じます。 JavaBeansイベント・モデルの規定では、いったんイベント通知を送信したら、イベント・ソースをさらに変更する前にすべてのリスナーに通知する必要があります。 また、配信の順序は保証されません。

通知は、2つの別個のイベント、DocumentEventUndoableEditEventとして提供されます。 APIを介してDocumentが変更された場合、登録されているすべてのDocumentListenersDocumentEventが送信されます。 Documentの実装が元に戻す機能や再実行機能をサポートしている場合、登録されているすべてのUndoableEditListenerUndoableEditEventが送信されます。 取消し可能な編集が取り消された場合、DocumentからDocumentEventをトリガーして再度変更されたことが示されます。 しかしこの場合、その編集はAPIを介して行われたDocumentの変更というよりむしろソースの変更であるため、UndoableEditEventは生成されません。

前の文は、この図について説明しています。

上記の図に関して、左に示されているコンポーネントが青い矩形で表されているドキュメント・オブジェクトを変更したと仮定します。 ドキュメントは両コンポーネントのビューにDocumentEventを送信して応答し、履歴バッファを保持しているリスニング・ロジックにUndoableEditEventを送ります。

上記の図に関して、右に示されているコンポーネントが青い矩形で表されているドキュメント・オブジェクトを変更したと仮定します。 ドキュメントは両コンポーネントのビューにDocumentEventを送信して応答し、履歴バッファを保持しているリスニング・ロジックにUndoableEditEventを送ります。

その後、履歴バッファがロールバックされる(つまり、最後のUndoableEditが実行されない)と、DocumentEventが両ビューに送られ、両ビューは実行されなかったドキュメントの変更を反映させます(つまり、右のコンポーネントの変更を削除します)。 履歴バッファが再度別の変更をロールバックすると、さらに別のDocumentEventが両ビューに送られ、実行されなかったドキュメントの変更を反映させます。つまり、左のコンポーネントの変更を削除します。

ドキュメントの変化に関係するメソッドは次のとおりです。

プロパティ

通常、Documentの実装には実行時に関連したプロパティ・セットがあります。 よく知られた2つのプロパティは、Documentがどこから出されたものかを記述するときに使用するStreamDescriptionPropertyDocumentに名前を付けるときに使用するTitlePropertyです。 プロパティに関係するメソッドは次のとおりです。

概要とプログラミングのヒント

Elementは、Documentの構築に使用される重要なインタフェースです。 段落、テキスト行、リスト内の(HTMLドキュメント内)アイテムなど、ドキュメントの様々な構造部分を記述する機能があります。 概念上、ElementインタフェースはSGMLドキュメントのスピリットの一部を取得します。 したがって、SGMLがわかっている場合は、Swing Elementインタフェースについて理解していることがあります。

SwingテキストAPIドキュメント・モデルでは、インタフェース要素は、段落、テキスト行、HTMLドキュメントのリスト・アイテムなど、ドキュメントの構造部分を定義します。

すべての要素は、「ブランチ」または「リーフ」のいずれかです。 要素がブランチの場合、isLeaf()メソッドはfalseを返します。 要素がリーフの場合、isLeaf()はtrueを返します。

ブランチには任意の数の子を含めることができます。 リーフには子がありません。 ブランチに含まれる子の数を確認するには、getElementCount()をコールします。 要素の親を決定するには、getParentElement()をコールします。 ルート要素には親がないため、ルートでgetParentElement()をコールするとnullが返されます。

要素は、startOffsetで始まり、endOffsetの直前に終了するドキュメント内の特定のリージョンを表します。 ブランチ要素の開始オフセットは、通常、最初の子の開始オフセットです。 同様に、ブランチ要素の終了オフセットは通常、最後の子の終了オフセットです。

すべての要素は、getAttributes()をコールしてアクセスできるAttributeSetに関連付けられています。 要素およびAttributeSetは、基本的にキーと値のペアのセットです。 これらのペアは通常、マークアップに使用されます -- (要素のフォアグラウンド・カラー、フォント・サイズなどの決定など)。 ただし、AttributeSetに格納される内容は、モデルおよび開発者によって決まります。

Documentのルート要素(または要素)を取得するには、Documentインタフェースで定義されているgetDefaultRootElement()およびgetRootElements()メソッドをコールします。

Documentインタフェースは、文字の線形ビューをElement操作に変換します。 要素の構造を定義するのは、各文書の実装によって異なります。

PlainDocumentクラス

PlainDocumentクラスは、ルート・ノードがモデル内のテキスト行ごとに子ノードを持つ要素構造を定義します。 「図1」では、PlainDocumentによって2行のテキストがどのようにモデル化されるかが示されます。

前の文は、この図について説明しています。

「図2」では、これらの同じ2行のテキストが実際のコンテンツにどのようにマップされるかを示します:

前の文は、この図について説明しています。

PlainDocumentへのテキストの挿入

前述のように、PlainDocumentにはルート要素が含まれ、ルート要素にはテキストの各行の要素が含まれます。 テキストがPlainDocumentに挿入されると、各改行に要素が存在するために必要な要素が作成されます。 説明するために、前述の「図2」のオフセット2に改行を挿入するとします。 この目的を達成するには、次の構文を使用してDocumentメソッドinsertString()を使用します:

document.insertString(2, "\n", null);

insertString()メソッドを起動すると、Element構造は「図3」に示すようになります。

前の文は、この図について説明しています。

別の例として、「図2」で前述したように、オフセット2にパターン"新規テキスト"を挿入するとします。 この操作の結果は、「図4」に表示されます。

前の文は、この図について説明しています。

前述の図では、行番号と一致するように挿入後に行要素の名前が変更されています。 ただし、これを行うと、AttributeSetsは同じままになります。 たとえば、「図2」では、明細2のAttributeSetは「図4」の明細4のAttributeSetのAttributeSetと一致します。

PlainDocumentからのテキストの削除

テキストを削除すると、削除が複数の行にまたがる場合に構造が変更されます。 「図3」で前述したオフセット1から始まる7文字を削除することを検討してください。 この場合、2行目を表す要素は、削除されたリージョンに含まれているため、完全に削除されます。 行1と行3を表す要素は、削除されたリージョンに部分的に含まれているため結合されます。 したがって、結果は次のようになります:

前の文は、この図について説明しています。

デフォルトのStyledDocumentクラス

スタイル設定されたテキストに使用されるDefaultStyledDocumentクラスには、別のレベルの要素が含まれます。 この追加レベルは、各段落に異なるスタイルのテキストを含めることができるようにするために必要です。 「図6」に示されている2つの段落では、最初の段落に2つのスタイルが含まれ、2つ目の段落に3つのスタイルが含まれています。

前の文は、この図について説明しています。

「図7」には、これらの同じ要素がコンテンツにどのようにマップされるかが表示されます。

前の文は、この図について説明しています。

DefaultStyledDocumentへのテキストの挿入

前述のように、DefaultStyledDocumentでは、ルート要素に各段落の子要素が含まれるようにElement構造が保持されます。 次に、これらの各段落要素には、段落内のテキストの各スタイルの要素が含まれます。 たとえば、「図8」に示すように、ある段落を含むドキュメントがあり、この段落に2つのスタイルが含まれているとします。

前の文は、この図について説明しています。

オフセット2に改行を挿入する場合は、次のようにinsertString()メソッドを再度使用します:

 styledDocument.insertString(2, "\n",
                styledDocument.getCharacterElement(0).getAttributes());

この操作の結果は、「図9」に表示されます。

前の文は、この図について説明しています。

insertString()に渡されるAttributeSetは、Style 1の属性のAttributeSetと一致することに注意してください。 insertString()に渡されたAttributeSetが一致しなかった場合、結果は「図10」に示されている状況になります。

前の文は、この図について説明しています。

DefaultStyledDocumentからのテキストの削除

DefaultStyledDocumentからのテキストの削除は、PlainDocumentからのテキストの削除と似ています。 唯一の違いは、要素の追加レベルです。 上の図10のオフセット1で2つの文字を削除した場合はどうなるかを考慮してください。 段落1の2番目の要素は、削除されたリージョンに完全に含まれているため、削除されます。 段落1の最初の子の属性がParagraph2の最初の子の属性と一致した場合、結果は「図11」に表示されるものになります。

前の文は、この図について説明しています。

属性が一致しなかった場合は、「図12」に表示される結果が得られます。

前の文は、この図について説明しています。

StyledDocumentクラス

StyledDocumentクラスには、特定の範囲の文字要素に属性を設定できるsetCharacterAttributes()という名前のメソッドが用意されています:

 public void setCharacterAttributes
          (int offset, int length, AttributeSet s, boolean replace);

前のセクションで示した図では、図面に表示されているすべてのリーフ要素も文字要素であることを思い出してください。 つまり、setCharacterAttributes()メソッドを使用して属性を設定できます。

setCharacterAttributes()メソッドは4つの引数を取ります。 最初の引数と2番目の引数は、変更するドキュメント内のリージョンを識別します。 3番目の引数は新しい属性(AttributeSetとして)を指定し、4番目の引数は新しい属性を既存の属性(falseの値)に追加するかどうか、または文字要素が既存の属性を新しい属性(trueの値)に置き換えるかどうかを決定します。

たとえば、前述の「図9」の最初の3文字の属性を変更するとします。 setCharacterAttributes()に渡される最初の2つの引数は0および3です。 3番目の引数は、新しい属性を含むAttributeSetです。 この例では、4番目の引数が何であるかは考慮していません。

変更されたリージョン(0および3)の開始オフセットと終了オフセットが文字要素境界に該当するため、構造の変更は必要ありません。 つまり、文字要素スタイル1の属性のみが変更されます。

次に、構造の変更が必要な例を見てみましょう。 「図9」に表示されている最初の3文字を変更するかわりに、最初の2文字を変更します。 終了変更オフセット(2)は文字要素境界に該当しないため、オフセット2の要素は、オフセット2が2つの要素の境界になるように分割する必要があります。 開始オフセットが0で長さが2のsetCharacterAttributes()を起動すると、前述の結果が「図10」に表示されます。

StyledDocumentの段落属性の変更

StyledDocumentクラスには、段落要素の属性を変更するために使用できるsetParagraphAttributes()というメソッドが用意されています:

 public void setParagraphAttributes
         (int offset, int length, AttributeSet s, boolean replace);

このメソッドはsetCharacterAttributes()に似ていますが、段落要素の属性を変更できます。 StyledDocumentの実装によって、どの要素が段落であるかが定義されます。 DefaultStyledDocumentは、段落要素をcharacter要素の親要素として解釈します。 このメソッドを呼び出しても、構造は変更されません。段落要素の属性のみが変更されます。

EditorKitおよびViewを参照することをお薦めします。 ビューは特定の要素のレンダリングを担当し、EditorKitは要素に基づいて作成するビューを決定できるViewFactoryを担当します。

関連項目:
DocumentEvent, DocumentListener, UndoableEditEvent, UndoableEditListener, Element, Position, AttributeSet
  • フィールドのサマリー

    フィールド
    修飾子と型
    フィールド
    説明
    static String
    ドキュメントの初期化に使用するストリームの記述のプロパティ名です。
    static String
    ドキュメントのタイトルがある場合、そのプロパティ名です。
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    void
    ドキュメントに変更が加えられたときに通知の受信を開始するように、指定されたオブザーバを登録します。
    void
    ドキュメントに取消し可能な編集が加えられたときに通知の受信を開始するように、指定されたオブザーバを登録します。
    createPosition​(int offs)
    このメソッドを使用すると文字コンテンツのシーケンスの位置にマークが付けられます。
    ルート要素を返します。要素の構造にビューを割り当てる別のメカニズムが提供されないかぎり、このルート要素がビューのベースになります。
    ドキュメントの末尾を表す位置を返します。
    int
    ドキュメント内の現在のコンテンツの文字数を返します。
    ドキュメントに関連するプロパティを取得します。
    定義されているすべてのルート要素を返します。
    ドキュメントの先頭を表す位置を返します。
    getText​(int offset, int length)
    ドキュメントの指定部分内にあるテキストを取得します。
    void
    getText​(int offset, int length, Segment txt)
    ドキュメントの指定部分内にあるテキストを取得します。
    void
    insertString​(int offset, String str, AttributeSet a)
    コンテンツの文字列を挿入します。
    void
    putProperty​(Object key, Object value)
    プロパティとドキュメントを関連付けます。
    void
    remove​(int offs, int len)
    ドキュメントのコンテンツの一部を削除します。
    void
    指定されたオブザーバを通知リストから登録解除して、それ以上変更の更新を受信しないようにします。
    void
    指定されたオブザーバを通知リストから登録解除して、それ以上更新を受信しないようにします。
    void
    モデルが非同期的な更新をサポートしている場合、並行性が存在する状態でモデルを安全に描画できるようにします。
  • フィールド詳細

    • StreamDescriptionProperty

      static final String StreamDescriptionProperty
      ドキュメントの初期化に使用するストリームの記述のプロパティ名です。 ドキュメントがストリームから初期化され、ストリームについてなんらかの定義がある場合には、これを使います。
      関連項目:
      定数フィールド値
    • TitleProperty

      static final String TitleProperty
      ドキュメントのタイトルがある場合、そのプロパティ名です。
      関連項目:
      定数フィールド値
  • メソッドの詳細

    • getLength

      int getLength()
      ドキュメント内の現在のコンテンツの文字数を返します。
      戻り値:
      文字数>= 0
    • addDocumentListener

      void addDocumentListener(DocumentListener listener)
      ドキュメントに変更が加えられたときに通知の受信を開始するように、指定されたオブザーバを登録します。
      パラメータ:
      listener - 登録するオブザーバ
      関連項目:
      removeDocumentListener(javax.swing.event.DocumentListener)
    • removeDocumentListener

      void removeDocumentListener(DocumentListener listener)
      指定されたオブザーバを通知リストから登録解除して、それ以上変更の更新を受信しないようにします。
      パラメータ:
      listener - 登録するオブザーバ
      関連項目:
      addDocumentListener(javax.swing.event.DocumentListener)
    • addUndoableEditListener

      void addUndoableEditListener(UndoableEditListener listener)
      ドキュメントに取消し可能な編集が加えられたときに通知の受信を開始するように、指定されたオブザーバを登録します。
      パラメータ:
      listener - 登録するオブザーバ
      関連項目:
      UndoableEditEvent
    • removeUndoableEditListener

      void removeUndoableEditListener(UndoableEditListener listener)
      指定されたオブザーバを通知リストから登録解除して、それ以上更新を受信しないようにします。
      パラメータ:
      listener - 登録するオブザーバ
      関連項目:
      UndoableEditEvent
    • getProperty

      Object getProperty(Object key)
      ドキュメントに関連するプロパティを取得します。
      パラメータ:
      key - null以外のプロパティ・キー
      戻り値:
      プロパティ
      関連項目:
      putProperty(Object, Object)
    • putProperty

      void putProperty(Object key, Object value)
      プロパティとドキュメントを関連付けます。 提供される2つの標準的なプロパティ・キーは、StreamDescriptionPropertyおよびTitlePropertyです。 作成者などほかのプロパティも定義されます。
      パラメータ:
      key - null以外のプロパティ・キー
      value - プロパティ値
      関連項目:
      getProperty(Object)
    • remove

      void remove(int offs, int len) throws BadLocationException
      ドキュメントのコンテンツの一部を削除します。 これは、例外がスローされないかぎり、DocumentEvent.EventType.REMOVEタイプのDocumentEventを登録されているすべてのDocumentListenersに送ります。 リスナーへの通知はDocumentListenersのremoveUpdateを呼び出して行います。

      無理のない動作を同時に満たすために、変更を実行してからイベントを送信します。 これは、削除通知が送信されるときまでには、ドキュメントはすでに更新されcreatePositionが作成したマークも変更されているからです。 削除の場合は、削除範囲の終点は始点に収納されており、削除範囲内の任意のマークは範囲の始点に収納されています。

      図は、「The quick brown fox.」からの「quick」の削除を示しています。

      削除の結果Document構造が変更された場合は、変更に応じてどのElementsが挿入、削除されたのかという詳細も、生成されたDocumentEventに格納されます。 削除によって構造がどのように変化するかはDocumentの実装によります。

      Documentが元に戻す機能と再実行する機能をサポートする場合は、UndoableEditEventも生成されます。

      パラメータ:
      offs - 先頭からのオフセット>= 0
      len - 削除対象の文字数>= 0
      例外:
      BadLocationException - 削除範囲の一部がドキュメントの有効な部分でなかった場合。 例外内の位置は、最初に検出された不正な位置。
      関連項目:
      DocumentEvent, DocumentListener, UndoableEditEvent, UndoableEditListener
    • insertString

      void insertString(int offset, String str, AttributeSet a) throws BadLocationException
      コンテンツの文字列を挿入します。 これは、例外がスローされないかぎり、DocumentEvent.EventType.INSERTタイプのDocumentEventを登録されたDocumentListenerに送ります。 DocumentEventの配信はDocumentListenerのinsertUpdateを呼び出して行います。 生成されたDocumentEventのオフセットと長さは、実際Documentにどのような変更がされたのかを示します。

      図は、「The quick brown fox」への「quick」の挿入を示しています。

      挿入の結果Document構造が変更された場合は、変更に応じてどのElementsが挿入、削除されたのかという詳細も、生成されたDocumentEventに格納されます。 挿入によって構造がどのように変化するかはDocumentの実装によります。

      Documentが元に戻す機能と再実行する機能をサポートする場合は、UndoableEditEventも生成されます。

      パラメータ:
      offset - コンテンツを挿入するドキュメント内のオフセット。0以上。 指定位置やその後ろの変更を追跡するすべての位置が移動します。
      str - 挿入する文字列
      a - 挿入されたコンテンツに関連付ける属性。 属性がない場合はnullも可。
      例外:
      BadLocationException - 指定された挿入位置がドキュメント内の有効な位置でない場合
      関連項目:
      DocumentEvent, DocumentListener, UndoableEditEvent, UndoableEditListener
    • getText

      String getText(int offset, int length) throws BadLocationException
      ドキュメントの指定部分内にあるテキストを取得します。
      パラメータ:
      offset - テキストの望ましい開始位置を表す、ドキュメントのオフセット>= 0
      length - 望ましい文字列の長さ>= 0
      戻り値:
      長さ>= 0のString内のテキスト
      例外:
      BadLocationException - 範囲の一部がドキュメントの有効な部分でなかった場合。 例外内の位置は、最初に検出された不正な位置。
    • getText

      void getText(int offset, int length, Segment txt) throws BadLocationException
      ドキュメントの指定部分内にあるテキストを取得します。

      txtパラメータのpartialReturnプロパティがfalseの場合、Segmentで返されたデータは、要求された長さ全体になり、データの格納方法によってコピーになる場合とならない場合があります。 partialReturnプロパティがtrueの場合は、コピーを作成しなくても返すことが可能なテキストの量だけが返されます。 部分的に返すことで、ドキュメントの大部分をスキャンする場合のパフォーマンスが向上します。 部分的に返す方法でドキュメント全体にアクセスする例を次に示します。

      
      
         int nleft = doc.getDocumentLength();
         Segment text = new Segment();
         int offs = 0;
         text.setPartialReturn(true);
         while (nleft > 0) {
             doc.getText(offs, nleft, text);
             // do someting with text
             nleft -= text.count;
             offs += text.count;
         }
      
       

      パラメータ:
      offset - テキストの望ましい開始位置を表す、ドキュメントのオフセット>= 0
      length - 望ましい文字列の長さ>= 0
      txt - テキストを返す先のSegmentオブジェクト
      例外:
      BadLocationException - 範囲の一部がドキュメントの有効な部分でなかった場合。 例外内の位置は、最初に検出された不正な位置。
    • getStartPosition

      Position getStartPosition()
      ドキュメントの先頭を表す位置を返します。 返された位置は、変更を追跡してドキュメントの先頭に常に位置するために利用できます。
      戻り値:
      位置
    • getEndPosition

      Position getEndPosition()
      ドキュメントの末尾を表す位置を返します。 返された位置は、変更を追跡してドキュメントの末尾に常に位置するために利用できます。
      戻り値:
      位置
    • createPosition

      Position createPosition(int offs) throws BadLocationException
      このメソッドを使用すると文字コンテンツのシーケンスの位置にマークが付けられます。 このマークを使用してコンテンツの中で行われた挿入や削除のような変更を追跡できます。 挿入に関してのポリシーは、挿入位置がゼロでない限り、常に挿入は現在の位置よりも前にする(もっとも一般的なケース)ということです。挿入位置がゼロの場合は、元の位置に続けて挿入されます。
      パラメータ:
      offs - ドキュメントの先頭からのオフセット>= 0
      戻り値:
      位置
      例外:
      BadLocationException - 指定された位置が、関連するドキュメント内の有効な位置を示さない場合
    • getRootElements

      Element[] getRootElements()
      定義されているすべてのルート要素を返します。

      一般的にドキュメント構造は1つだけですが、インタフェースはテキスト・データに関して構造プロジェクションを任意の数だけ構築できるようにサポートしています。 ドキュメントは、複数のドキュメント構造をサポートする複数のルート要素を持つことができます。 次に、例をいくつか示します。

      • テキストの方向
      • 字句トークン・ストリーム
      • 構文木
      • ネイティブ以外の形式への変換
      • 変更の仕様
      • 注釈
      戻り値:
      ルート要素
    • getDefaultRootElement

      Element getDefaultRootElement()
      ルート要素を返します。要素の構造にビューを割り当てる別のメカニズムが提供されないかぎり、このルート要素がビューのベースになります。
      戻り値:
      ルート要素
    • render

      void render(Runnable r)
      モデルが非同期的な更新をサポートしている場合、並行性が存在する状態でモデルを安全に描画できるようにします。 指定された実行可能ファイルは、その実行中に何の変更もなくモデルを安全に読み取る方法で実行されます。 実行可能ファイルは、それ自身で変更を加えることはできません
      パラメータ:
      r - モデルを描画するために使用するRunnable