SwingのJTextComponentの拡張クラスを使えば、簡単にテキストエディターを実現できるのだが、
	任意倍率でテキストを含めた拡大/縮小表示ができそうにない(?)。
	このためInput Method framework, 
	Java 2D Graphics
	を使って簡単なテキストエディターを作成した。
英字の場合は、KeyListenerインターフェイスのkeyTypedメソッドで直接入力文字を受け取るが、
	日本語の場合はInputMethodListenerのinputMethodTextChangedメソッドでカナ∙
漢字変換された文字列を受け取ることができる。
灰色の枠が表示されているTextBoxには入力できない。一度クリックして枠をグリーンに変える。
	なおメニューボタンを押してTextBoxを作成したときは、グリーンの枠が表示されている。
英字入力の時は、ListenerPanelのkeyTypedメソッドでアルファベットを受け取り、TextBoxのkeyTypedメソッドへ送る。カナ∙
漢字入力モードの時は、ListenerPanelのinputMethodTextChangedメソッドでKeyEventを受け取り、
TextBoxのinputMethodTextChangedメソッドへ送る。
確定テキストはCommittedTextContainerに格納し、未確定テキストは確定テキストと合成して画面に表示する処理を行う。ここで確定テキストはEnterを押してカナ∙
    
      | 
				フィールド
       | 
      
      説明
       | 
    
    
      | 
      shapeContainer
       | 
      
      ShapeContainer shapeContainer 
      このTextBoxを持つ図形コンテナオブジェクト。
       | 
    
    
      | 
      textArea
       | 
      
      public Rectangle2D textArea=null 
      TextBoxのテキスト領域。 
      ∙ textAreaの設定 
      
				ShapeContainer.addTextBoxから
				ShapeElement.createTextArea抽象(abstract)メソッドを呼んで
				textAreaを取得し、addTextBoxメソッドでTextBoxに設定する。 
				
			 
      ∙ textAreaを移動/リサイズする 
      
				ShapeElement.moveResizeメソッドから
				TextBox.resizeTextAreaメソッドを呼んでtextAreaの移動/リサイズを行う。
			 
       | 
    
    
      | 
      textBoxInsets
       | 
      
      public Insets textBoxInsets= new Insets(2, 2, 2, 2) 
      TextBox内部の余白部分
       | 
    
    
      | 
      textAlign
       | 
      
      public int textAlign 
      テキストの配置 右寄せ(0)/中央寄せ(1)/左寄せ(2)
       | 
    
    
      | 
      lineSpace
       | 
      
      public int lineSpace 
      テキストの行間隔
       | 
    
    
      | 
      currentFontStyle
       | 
      
				private FontStyle currentFontStyle 
				keyTypedメソッド、inputMethodTextChangedメソッドにより入力した文字列には、
				このフィールド変数のFontStyleオブジェクトを
				FontStyle.setToメソッドで設定する。
       | 
    
    
      | 
      committedTextContainer
       | 
      
				private CommittedTextContainer committedTextContainer 
      確定テキスト(committed text)を格納する
			CommittedTextContainerオブジェクトを設定する。
       | 
    
    
      | 
      composedTextIterator
       | 
      
				private AttributedCharacterIterator composedTextIterator 
				composedTextは未確定テキストのこと。日本語入力の場合はカナ∙ 漢字変換が確定する前の変換候補の文字列。
				未確定テキストをcomposedTextIteratorに設定する。
       | 
    
    
      | 
      lineBreaker
       | 
      
				private LineBreaker lineBreaker 
				LineBreakerオブジェクトを設定する。
				LineBreakerは属性つきテキストを、指定幅の行に割り付けるクラスである。
       | 
    
    
      | 
				validTextLayout
       | 
      
				private boolean validTextLayout 
        LineBreakerオブジェクトを作り直す必要があるとき(テキスト挿入∙ 削除, FontStyle変更時など)にfalseを設定する。
				falseが設定されているとLineBreakerを呼んでテキストを行に再割付する。
       | 
    
    
       | 
				caretPosition
       | 
      
				public CaretPosition caretPosition 
				CaretPositionオブジェクトを設定する。
				現在のキャレット位置を表す。 
				初期値はnew CaretPosition(0 , 0, 0)。 
				(注)キャレットの位置 
				テキストをLineBreakerで複数行に割り付けた際の2次元的な位置(行番号と行での位置で表す)と、
				テキストの先頭から数えた1次元的な位置の両方が使われ、これらは同期が取られる必要がある。
				同期を取るためには、LineBreakerが作成するTextLayoutデータが必要である。 
         =>
				CaretPosition
       | 
    
    
      | 
				selStart
       | 
      
				private CaretPosition selStart 
				選択文字列の先頭のキャレット位置。初期値はnew CaretPosition(-1 , -1)。
       | 
    
    
      | 
				selEnd
       | 
      
				private CaretPosition selEnd 
				選択文字列の後のキャレット位置を。初期値はnew CaretPosition(-1 , -1)。 
				 : selStartは画面で見て左上、selEndは右か右下方向になっていること。 
				これが逆転していると、選択文字列のハイライト表示、選択文字列への属性設定など、多くの部分でエラーになる。
				このクラスのsetTextSelectionメソッドで selStartとselEndの順番をチェックする。
       | 
    
    
      | 
				dragStart
       | 
      
				private CaretPosition dragStart 
        ドラッグ開始キャレット位置。mousePressedで設定。初期値はnew CaretPosition(-1 , -1)。
			 | 
    
    
      | dragEnd | 
      
				private CaretPosition dragEnd 
				ドラッグ中または終了時のキャレット位置。mouseDragged, mouseReleasedで設定。 
        初期値はnew CaretPosition(-1 , -1)。
			 | 
    
    
      | 
      mousePositionInfo
       | 
      
				MousePositionInfo mousePositionInfo 
				現在のマウス位置がTEXTBOX_BOUNDARY(マウス位置コード)ならば、
				MousePositionInfoオブジェクトをこのフィールドに設定する。
				このフィールドは mousePressed メソッドで参照される。 
				 =>
				操作説明書 
				テキストボックス境界の移動
       | 
    
    
      | 
      modified
       | 
      
				boolean modified 
				テキストボックス境界の移動が行われたら、このフィールドをtrueにする。
				このフィールドはmousePressed と 
				mouseReleaed メソッドで参照される。
       | 
    
    
      | 
				oldPoint
       | 
      
				Point2D oldPoint 
				マウス位置をセット。
       | 
    
    
      | 
				newPoint
       | 
      
				Point2D newPoint 
				マウス位置をセット。
       | 
    
    
      | 
      connectionUtil
       | 
      
				ConnectionUtil connectionUtil 
				テキストボックス境界の移動が行われるときにConnectionUtil
				オブジェクトをセット。
       | 
    
    
      | UndoSetupDeleteText | 
      private TextUndoSetup.DeleteText UndoSetupDeleteText 
				TextUndoSetup.DeleteTextオブジェクト | 
    
    
      | UndoSetupInsertText | 
      private TextUndoSetup.InsertText UndoSetupInsertText 
      TextUndoSetup.InsertTextオブジェクト | 
    
    
      | KEY_BOARD | 
      
				final public static int KEY_BOARD=0 
      テキスト挿入/削除方法の識別子。TextBox.keyTypedメソッドで指定する。 | 
    
    
      INPUTMETHOD _TEXTCHANGED | 
      
				final public static int INPUTMETHOD_TEXTCHANGED=1 
				テキスト挿入/削除方法の識別子。TextBox.inputMethodTextChangedメソッドで指定する。 | 
    
    
      | COMMAND | 
      
				final public static int COMMAND=3 
				テキスト挿入/削除方法の識別子。Edit.copyString, Edit.pasteString, Edit.pasteAttributedString,
				Edit.deleteメソッドなどで指定する。 | 
    
    
      | UNDO_REDO | 
      
				final public static int UNDO_REDO=4 
				テキスト挿入/削除方法の識別子。TextBox.insertText, TextBox.deleteText, UndoableDrawEdit.ChangeText,
				UndoableDrawEdit.InsertText, UndoableDrawEdit.DeleteTextで指定する。 
				 :
				当たり前であるが、undo、redoのテキスト挿入/削除操作に対してはundo設定は行わない。
			 | 
    
    
      | 
      メソッド
       | 
      
				説明
       | 
    
    
      | 
				コンストラクタ
       | 
      
				public TextBox () 
				ListenerPanel.requestFocus()を呼ぶ。
       | 
    
    
      | getShapeContainer | 
      
				public ShapeContainer getShapeContainer() 
      フィールド変数shapeContainerを返す。 | 
    
    
      | setShapeContainer | 
      
				public void setShapeContainer(ShapeContainer container)
				フィールド変数shapeContainerに引数を設定。 | 
    
    
      | 
      activateMouseListener
       | 
      
      public void activateMouseListener(boolean activate) 
      引数: 
      activate - trueならばこのテキストボックスを編集可能にする。falseならば編集不能にする。 
      処理: 
      ElementeContainer.makeTextBoxEditableメソッドから呼ばれる。 
      ∙ activate=trueのとき 
      ListenerPanelにこのTextBoxをマウスリスナー、マウスモーションリスナーとして設定する。
				    listenerPanel.addMouseListener(this); 
				    listenerPanel.addMouseMotionListener(this);
			 
      ∙ activate=false 
			ListenerPanelからこのTextBoxを削除する。 
          listenerPanel.removeMouseListener(this); 
          listenerPanel.removeMouseMotionListener(this);
			 
       | 
    
    
      | 
      isEditable
       | 
      
      public boolean isEditable 
      このテキストボックスが編集可能ならばtrueを返す。
       | 
    
    
      | 
      getBoundingBox
       | 
      
      public Rectangle2D getBoundingBox() 
      このTextBoxを囲むBoundingBoxを返す。
       | 
    
    
      | getTextArea | 
      
      public Rectangle2D getTextArea() 
      フィールド変数textAreaを返す。 | 
    
    
      | 
      setTextArea
       | 
      
      public void setTextArea(Rectangle2D textArea) 
      フィールド変数textAreaに引数を設定する。
       | 
    
        | getMarginlessTextArea | 
        public Rectangle2D getMarginlessTextArea() 
        textAreaからtextBoxInsetsを差し引いた領域を返す。 | 
      
        | getTextLayoutArea | 
        public Rectangle2D getTextLayoutArea() 
        LineBreaker.getBoundsメソッドでテキストを折り返し表示する行の矩形領域を配列で受け取り、その矩形領域をすべて覆う矩形領域を返す。 | 
      
      | 
      getCommittedTextContainer
       | 
      
      public CommittedTextContainer getCommittedTextContainer() 
      フィールド変数committedTextContainerを返す。
       | 
    
    
      | 
      isCommittedText
       | 
      
      public boolean isCommittedText() 
      committedTextがnullでなければtrueを返す。
       | 
    
    
      | getTextLocation | 
      
      public Rectangle getTextLocation() 
      ListenerPanel.getTextLocationから呼ばれる。 
			LineBreaker.getCaretRectangleの戻り値を返す。
       | 
    
    
      | 
      resizeTextArea
       | 
      
				public void resizeTextArea(Rectangle2D oldBox, Rectangle2D newBox) 
				setTextAreaメソッドでテキスト領域をリサイズする。 
        このTextBoxを所有するShapeContainerの図形要素のリサイズメソッド
				(ShapeElement.moveResize)から呼ばれる。
         | 
    
    
      | 
      getTextBoxInsets
       | 
      
      public Insets getTextBoxInsets() 
      フィールド変数textBoxInsetsを返す。
       | 
    
    
      | 
      setTextBoxInsets
       | 
      
      public void setTextBoxInsets(Insets insets) 
      textBoxInsetsに引数を設定する。
       | 
    
    
      | 
      getTextLineSpace
       | 
      
      public int getTextLineSpace() 
      フィールド変数lineSpaceを返す。
       | 
    
    
      | 
      setTextLineSpace
       | 
      
      public void setTextLineSpace(double lineSpace) 
      フィールド変数lineSpaceに引数を設定する。
       | 
    
    
      | getTextAlign | 
      
      public int getTextAlign() 
      フィールド変数textAlignを返す。 | 
    
    
      | 
				setTextAlign
       | 
      
      public void setTextAlign(int textAlign) 
      フィールド変数textAlignに引数を設定。
       | 
    
    
      | setTextBoxLayout | 
      
      public void setTextBoxLayout(Insets textBoxInsets, int textAlign, double lineSpace) 
      フィールド変数textBoxInsets、lineSpace、textAlignに引数の値を設定。 | 
    
    
      | 
      setFontStyle
       | 
      
				public void setFontStyle(FontStyle newFontStyle) 
				ExecCommandから呼ばれる。 
      ∙ 選択テキストがあるとき 
       選択テキストに引数のnewFontStyleを設定する。
				 設定メソッドはFontStyle.setTo。
			  
      ∙ 選択テキストがないとき 
       CommittedTextContainerが保持する確定テキスト全体にnewFontStyleを設定する。
			  
       | 
    
		
      | getFontColors | 
      public Color[] getFontColors() 
        このメソッドはShapeContainer.getColorsメソッドから呼ばれる。
				このオブジェクトのCommittedTextContainer
				オブジェクトで使われている全ての色情報を配列で返す。
			 | 
     
		
      | getSerializableTextBox | 
      
				public SerializableTextBox getSerializableTextBox() 
				このTextBoxからフィールド変数だけを取り出したSerializableTextBoxを返す。 
				このメソッドはUndoableDrawEdit.ChangeTextBoxで使われる。 | 
    
    
      | setSerializableTextBox | 
      
      public void setSerializableTextBox(SerializableTextBox data) 
      SerializableTextBoxのデータをこのTextBoxに設定。 
      このメソッドはUndoableDrawEdit.ChangeTextBoxで使われる。 | 
    
    
      | 
      toString
       | 
      
      public String toString() 
      このTextBoxの文字列表現を返す。
       | 
    
    
      | 
      setValidTextLayout
       | 
      
      private void setValidTextLayout(boolean valid)
      フィールド変数validTextLayoutに引数を設定する。 
        TextBox内のテキストが変更された場合valid=falseを指定する。
				valid=falseが設定されている場合、drawText
				でLineBreakerオブジェクトが作り直され、テキストが再配置される。
       | 
    
    
      | 
      keyTyped
       | 
      
      public void keyTyped(char keyChar) 
      ListenerPanelにインプリメントされているkeyTypedから呼び出される。 
        FontStyleの設定されたキャラクターを、このクラスのinsertTextメソッドで、
				CommittedTextContainerに挿入し、undo設定を行う。 
        引数: 
					keyChar - 入力文字. 
        処理: 
        このメソッドは ListenerPanel.keyTyped メソッドから呼ばれる。 
        ∙ deleteSelectedTextメソッドを呼んで、選択されたテキストがあれば削除。 
         this.deleteSelectedText(TextBox.KEY_BOARD);  
        ∙ 引数 keyCharをAttributedStringに変換。 
         AttributedString attribChar=new AttributedString(String.valueOf(keyChar)); 
        ∙ 上記attribChar をCommittedTextContainerに挿入する。 
        this.insertText
					(TextBox.KEY_BOARD, insertionIndex, attribChar.getIterator()); 
        ∙ this.setValidTextLayout(false);
  
        
         =>
				図1 テキスト入力手順
       | 
    
    
      | 
      keyPressed
       | 
      
				public void keyTyped(int keyCode) 
        引数: 
				keyCode - 入力文字コード. 
        処理: 
        このメソッドは ListenerPanel.keyPressedから呼ばれ、
				テキストカーソルを左右、上下に動かす。 
        ∙ KeyCodeがKeyEvent.VK_LEFTまたはKeyEvent.VK_RIGHTの場合 
				 CaretPosition.columnOffsetメソッドを呼んで、
					キャレットの位置を左右にひとつ動かす。
				 
				∙ KeyCodeがKeyEvent.VK_UPまたはKeyEvent.VK_DOWNの場合 
				 CaretPosition.lineOffsetメソッドを呼んで、
					キャレットの位置を上下にひとつ動かす。
				 
				  =>
					ListenerPanel java.awt.event.KeyEventで受け取る値
       | 
    
    
      | 
      inputMethodTextChanged
       | 
      
      public void inputMethodTextChanged(InputMethodEvent event) 
      InputMethod Frame WorkのInputMethodListenerの定義するメソッド。 
      このメソッドはListenePaneのinputMethodTextChangedから
			InputMethodEvent eventを受け取る。 
      ∙ eventの確定テキスト 
      このクラスのinsertTextメソッドでCommittedTextContainerに挿入する。
			 
      ∙ eventの未確定テキスト 
      TextAttribute.INPUT_METHOD_HIGHLIGHT属性を付けてフィールド変数
				composedTextIteratorに設定。
				さらにフィールド変数のcurrentFontStyleを設定する。
			 
      composedTextIteratorはgetDisplayTextで
				確定テキストに挿入され画面に表示される。
				このとき選択テキストがあれば、このクラスのdeleteSelectedTextで削除する
				(選択テキストへの上書き)。
			 
       =>
			図1 テキスト入力手順
       | 
    
    
      | 
      printInputMethodStatus
       | 
      
      private void printInputMethodStatus(InputMethodEvent event) 
      inputMethodTextChangedの状態をプリントする。デバッグ用。
       | 
    
    
      | 
      insertText
       | 
      
      public void insertText(int method, int position, AttributedCharacterIterator attribStr) 
      CommittedTextContainer.insertTextでCommittedTextContainerにテキストを挿入する。 
      引数: 
				method - TextBox.KEY_BOARD, TextBox.INPUTMETHOD_TEXTCHANGED、TextBox.PASTE, TextBox.UNDO_REDOのどれかを指定。 
				position - 挿入位置 
				attribStr - 挿入テキスト 
      処理:
  
			
			(a)method がTextBox.KEY_BOARDまたは TextBox.INPUTMETHOD_TEXTCHANGEDの場合 
				∙ committedTextを取り出し、挿入位置(position)の手前の文字のFontStyle(fontStyle)を取得する。 
        AttributedCharacterIterator iterator=committedText.getIterator(); 
					FontStyle fontStyleAt=FontStyle.getFontStyleAt(iterator, position); 
					if(!FontStyle.isDefaultFontStyle(fontStyleAt)) fontStyle=fontStyleAt; 
				 
        ∙ 挿入テキストattribStrにfontStyleを設定する。 
        insertStr = fontStyle.setTo(attribStr, 0, attribStr.getEndIndex());  
				 
				
				(b)method がTextBox.COMMANDの場合 
				挿入テキストattribStrにFontStyleが設定されているか否か調べる。 
					boolean isFontStyle=FontStyle.isFontStyle(attribStr, attribStr.getBeginIndex(),
					attribStr.getEndIndex()) 。 
					設定されていなければ、(a)と同様にcommittedTextの挿入位置(position)の手前の文字のFontStyleをattribStrに設定する。
				  
				(c)後処理 - (a)(b)共通 
        ∙ committedTextContainerに挿入文字列(insertStr)を挿入 
        this.committedTextContainer.insertText(insertionIndex, insertStr)  
        ∙ LineBreakerで文字列を複数行に配置しなおす。 
        ∙ キャレット(文字カーソル)位置を更新。 
        キャレットのテキスト位置を挿入テキストの後に設定し、
					CaretPosition.updateCaretPosition
					メソッドで更新。 
        ∙ methodがTextBox.UNDO_REDOでなければundo設定を行う
				TextUndoSetup.InsertText)。
  
				
         : 
					テキストの挿入は、TextBox内部、外部を問わず、全てこのメソッドを通るようにし、ここでundoの設定を行う。
       | 
    
    
      | 
      deleteSelectedText
       | 
      
      private void deleteSelectedText(int method) 
      フィールド変数selStart, 
			selEndから選択テキストの範囲を取得しdeleteTextメソッドで削除。
       | 
    
    
      | 
      deleteText
       | 
      
      public void deleteText(int method, int start, int end) 
      CommittedTextContainerの確定テキストのstart, end間を削除する。 
      引数: 
      method - TextBox.KEY_BOARD, TextBox.INPUTMETHOD_TEXTCHANGED、TextBox.PASTE,  TextBox.UNDO_REDOのどれかを指定。 
      start, end - 削除文字列の開始、終了位置 
      処理: 
      ∙ CommittedTextContainer.deleteTextでstart, end間のテキストを削除。 
      ∙ キャレット(文字カーソル)位置を更新。 
       キャレットのテキスト位置をstartに設定し、
				LineBreaker.updateCaretPositionメソッドで更新。
			 
      ∙ methodがTextBox.UNDO_REDOでなければ、undoの設定を行う
			(TextUndoSetup.deleteText)。 
       :
				テキストの削除は、TextBox内部、外部を問わず、全てこのメソッドを通るようにし、
						ここでundoの設定を行う
       | 
    
    
      | 
				deleteTextByDelCommandOrBSkey
       | 
      
				public int deleteTextByDelCommandOrBSkey(int method) 
				Edit.deleteだけから呼ばれる。
				deleteコマンドでテキストを削除する場合の処理メソッド。 
				テキストを選択しておいてdeleteコマンドまたはBack spaceキーで一括削除する場合と、
				Back spaceキーでカーソルの前の文字を一文字づつ削除する場合がある。 
				削除する文字列のstart, endを決め、上のdeleteTextメソッドを呼んで削除。 
				戻り値は削除した文字数を返す。
       | 
    
    
      | replaceText | 
      
      public void replaceText(int method, AttributedString attribStr) 
      UndoableEdit.ChangeTextのundo、redoメソッドから呼ばれる。undo、redoでCommittedTextContainerの確定テキストを全部リプレースする。CommittedTextContainer
      setCommittedTextで処理。 | 
    
    
      | 
      getComposedText
       | 
      
      public AttributedCharacterIterator getComposedText() 
      未確定テキスト(フィールド変数committedTextIterator)を返す。
       | 
    
    
      | 
      getDisplayText
       | 
      
				public AttributedCharacterIterator getDisplayText() 
				画面に表示するテキストを取得する。 
				未確定テキスト(ComposedText)が存在しない場合、CommittedTextContainerの確定テキストだけを表示テキストとする。 
				未確定テキスト(ComposedText)が存在する場合、
				CommittedTextContainer.getDisplayTextメソッドに
				未確定テキストを引数で渡し、確定テキストと未確定テキストを合成したテキストを作成し表示テキストとする。 
				 : 
				確定テキストと未確定テキストの合成はCommittedTextContainer.getDisplayTextから呼ばれる
				AttributedStringUtil.createCompositeTextメソッドで行う。
       | 
    
    
      | 
      drawTextBox
       | 
      
      public void drawTextBox(Graphics g) 
      TextBox描画のメインメソッド。
			TextBoxを所有する図形(ShapeContainer)はShapeContainer.drawShapeメソッドで描画するので、
			このメソッドではTextBox内部を描画する。 
      ∙ テキスト領域:drawTextArea 
      テキストを囲む枠を表示する。
				TextBoxがactive(テキスト入力∙ 編集可能)の場合は緑色の枠、そうでないときは灰色の枠を描画する。
			 
      ∙ テキスト:drawText 
       LineBreakerで複数行に分割。LineBreakerから複数行に対応するTextLayoutの配列を取得して、
				TextLayout.drawメソッドでテキストを描画する。
			 
      ∙ キャレット(文字カーソル):drawCaret 
      TextBoxがactiveの場合に描画する。 
      ∙ キャレット(文字カーソル):drawTextSelection 
      TextBoxがactiveの場合で、テキストが選択されているときに選択文字列の背景にハイライトを描画。 
       | 
    
    
      | 
      drawTextArea
       | 
      
				public void drawTextArea(Graphics g) 
				テキスト領域を示す枠を表示する。枠の色は、このTextBoxがactive(テキスト入力∙ 編集可能)なときは Color.GREEN、
				そうでない時はColor.LIGHT_GRAY。 
        枠は、getShrinkedRectangleを使い、TextBox領域の少し内側に描画する。
       | 
    
    
      | 
      drawText
       | 
      
				public void drawText(Graphics g) 
				TextBox内のテキストを表示する。
  
				
				∙ validTextLayoutがfalseの場合: 
				LineBreakerを呼んでテキストを枠で折り返し複数行に割り付ける。
					CaretPosition.updateCaretPositionメソッドで 
					selStart, selEnd, 
					caretPositionフィールドを更新する。
				 
         : LineBreakerによる行の再割り付け 
        選択テキストのフォントスタイルを変更する場合など、例えば太字、イタリックに変えると文字の幅が変わる。このためselStart, selEndのフィールド変数値lineIndex, columnIndexは無効になるが、textIndex値は有効である。そこでCaretPosition.updateCaretPositionメソッドでselStart, selEndのtextIndex値からlineIndex, columnIndex値を再計算してselStart, selEndに設定しなおす。
					これでdrawTextSelectionでテキスト選択範囲が正しく表示される。
				  
				
        ∙ LineBreaker結果はjava.awt.font.TextLayoutの配列に格納される。 
        TextLayoutの配列は
					LineBreaker.getTextLayoutsで取得。
					各配列は1行に対応しており、属性付き文字列(AttributedCharacterIterator形式)が格納されている。
					また各TextLayoutの表示位置は、
					LineBreaker.getTextLayoutPositionsで取得する。
				  
				
        ∙ 各配列をjava.awt.font.TextLayout.drawメソッドで表示する。 
        
        textLayouts[i].draw(g2, (float)positions[i].getX(), (float)positions[i].getY())
				 
        各TextLayoutの表示位置は、TextLayoutのベースラインの左端。 
					表示位置:  => 
					LineBreaker.createMultipleLines
				  
				
				∙ DrawParameters.DRAW_TEXTLAYOUTがtrueの場合: 
				java.awt.font.TextLayout boundsを描画する。 
				
					  
					 通常表示Draw TextLayout bounds
				 
         | 
    
    
      | 
      drawCaret
       | 
      
      public void drawCaret(Graphics g, int offset) 
      キャレットを表示する。引数offsetは現在のキャレット位置からのオフセット。 
      未確定テキスト(カナ∙ 漢字変換候補テキスト)が入力された場合、未確定テキストの後ろにキャレットを表示したい。 
      一方キャレットの位置(フィールド変数caretPosition)は、
			確定テキストの挿入、削除で更新するようにしているため、未確定テキストが入力された時点では、
			未確定テキストの手前に位置している。 
      引数offsetには未確定テキストの長さを指定し、未確定テキストの後ろにキャレットを表示するためのものである。 
      ∙ オフセットしたキャレット図形を取得。 
      LineBreaker.getCaretRectangleメソッドに
				キャレットの現在位置とオフセット量を渡し、キャレットを表す矩形を取得する。
			 
      ∙ g2.draw(caretRectangle)でキャレットを描画。  
       :
			LineBreaker.getCaretRectangleについて
			 
      キャレット図形は、java.awt.font.TextLayoutのメソッドで取得する。 
      textLayout.getCaretShapes(position); 
      TextBoxにまだテキストが入力されていない段階では、TextLayoutオブジェクトは作成されていない。
			この時getCaretRectangleメソッドでは、仮のTextLayoutを作成してキャレット図形を取得するなどの特殊処理が必要になる。
			またenterキーを押して改行した場合にも、
			その行に対応するTextLayoutオブジェクトが作成されていないので同様な処理が必要になる。結構面倒である。
       | 
    
    
      | 
      drawTextSelection
       | 
      
      public void drawTextSelection(Graphics g) 
        選択テキストにハイライトを表示する。テキストの選択は複数行にまたがるので、
				ハイライトの表示も複数行にまたがる。
				ハイライト図形(java.awt.Shape)はjava.awt.font.TextLayoutクラスのgetLogicalHighlightShapeメソッドで取得する。 
        LineBreaker.getTextLayouts、
				LineBreaker.getTextLayoutPositionsメソッドにより、
				複数行に対応するTextLayout配列と各TextLayoutの位置を格納したPoint2D配列(positions)を取得。 
        各TextLayoutからjava.awt.font.TextLayout.getLogicalHighlightShapeメソッドでハイライトを取得し描画する。 
        ∙ テキスト選択範囲の開始行(startLine)、終了行(endLine)を
				CaretPosition.getLineIndexメソッドで取得 
        またstartLineとendLineでの開始、終了文字インデックス(startColumnIndexとendColumnIndex)を
					CaretPosition.getColumnIndexで取得。 
        ∙ TextLayoutオブジェクトの配列を
				LineBreaker.getTextLayoutsメソッドで取得。 
        選択範囲を表すハイライト形状をつぎのように取得 
           Shape highlight=textLayouts[i].getLogicalHighlightShape(start, end); 
        i=startLineならば, start=startColumnIndex 
        i=endLineならば, end=endColumnIndex 
        startLine<i<endLineならば、start=0, end= (textLayouts[i]の文字数) 
        ∙ ハイライトの描画 
         if(highlight!=null) g2.fill(highlight); 
        ∙ 選択テキストの描画 
          textLayouts[i].draw(g2, (float)positions[i].getX(), (float)positions[i].getY()); 
        テキストはdrawTextメソッドで描画されるが、ハイライトで上書きされるので、ここで再度描画する。 
         | 
    
    
      | getTextIndex | 
      
      public int getTextIndex()
      キャレットの位置をcommittedTextのテキスト位置で返す。Editオブジェクト
			DialogOfShapeFormatオブジェクトから呼ばれる。
       | 
    
    
      | hasSelectedText | 
      
      public boolean hasSelectedText() 
      選択されたテキストがあるか時trueを返す。
       | 
    
    
      | getSelectedTextStart | 
      
      public int getSelectedTextStart() 
      選択されたテキストの先頭位置を返す。DialogOfShapeFormatオブジェクトから呼ばれる。
       | 
    
    
      | getSelectedTextEnd | 
      
      public int getSelectedTextEnd() 
      選択されたテキストの終了位置を返す。
       | 
    
    
      | 
      getSelectedText
       | 
      
      public AttributedString getSelectedText() 
      選択されたテキストの取り出し。Editオブジェクトから呼ばれる。
       | 
    
    
      | 
      mousePressed
       | 
      
      public void mousePressed(MouseEvent e) 
      次の2つの操作が mousePressed, mouseDragged, mouseReleased メソッドで実行される。第1の操作はテキストボックスの境界移動
      (操作説明書  テキストボックス境界の移動). 
			第2の操作はマウスドラッグによるテキストの選択 (操作説明書 
			テキスト選択). 
  
			
      (1)テキストボックス境界の移動 
      ∙ 現在の MousePositionInfo 
			オブジェクトを MousePositionLS.getAllMousePositionInfo
			メソッドで取得。 
      MousePositionInfoの マウス位置コード が 
				TEXTBOX_BOUNDARY ならば、その MousePositionInfo オブジェクトを 
				mousePositionInfo フィールドに設定する。
			 
      ∙ mousePositionInfo がnullでなければ次の処理を実行する。 
      
				(a)modifiedフィールドにtrueをセット 
				(b)ConnectionUtil オブジェクトを作成し、
					ConnectionUtil.setTargetsメソッドを呼ぶ。 
				(c)ContainerManager.undoSetupStart 
					メソッドを呼んでundoの設定を行う。
			  
			
      (2)テキスト選択 
      ∙ 未確定テキストがフィールド変数composedTextIteratorに
			セットされているとき 
       カナ∙ 漢字変換中なので警告メッセージのダイアログを表示してリターン。
			  
      ∙ このクラスのgetCaretPositionAtMouseメソッドにマウス位置(X,Y)を渡し、
			キャレット位置を取得。 
      ドラッグ開始点をフィールド変数dragStartに設定。 
       | 
    
    
      | 
      mouseDragged
       | 
      
      public void mouseDragged(MouseEvent e)
  
      (1)テキストボックス境界の移動 
      ∙ MousePositionInfo.getInformation 
			メソッドでテキストボックスの境界のエッジを取得し、textAreaの
			矩形のデータを設定しなおすことでそのエッジを動かす。 
      ∙ 境界のエッジを大きく動かしたときは ShapeElement.moveResize 
			メソッドで図形自体をリサイズする。
			もしコネクターが接続しているときは、
			ConnectionUtil.resizeConnectorsメ
			ソッドでコネクターの接続を維持する。
  
			
      (2)テキスト選択 
      ∙ 未確定テキストがフィールド変数composedTextIteratorにセットされているときmousePressedと同様リターン。 
      ∙ このクラスのgetCaretPositionAtMouseメソッドにマウス位置(X,Y)を渡し、
			キャレット位置を取得。 
       ドラッグ現在点としてフィールド変数endCaretPositionに設定。 
			 ∙ このクラスのsetTextSelectionメソッドを呼んで選択区間を設定する。 
      
				フィールド変数dragStartとdragEndの
				間をテキスト選択区間として設定する。 
       テキスト選択区間はフィールド変数selStart, 
			 selEndで表す。
			 
       : 
			setTextSelectionではマウスを左下から右上に動かした場合、
			選択範囲が逆転するので、それを防止する処理を行う。 
       :
			テキスト選択区間はdrawSelectionメソッドによりハイライトを表示する。
       | 
    
    
      | 
      mouseReleased
       | 
      
      public void mouseReleased(MouseEvent e)
  
			
      (1)テキストボックス境界の移動 
      もし modifiedフィールドがtrueならば、
				変更コード (UndoConstants.CONTAINER) を ShapeContainerに設定し、
				ContainerManager.undoSetupEndメソッドを呼ぶ。
			  
			
      (2)テキスト選択 
      マウスボタンが離される時に、テキスト選択範囲が確定する。 
      ∙ このクラスのgetCaretPositionAtMouseメソッドにマウス位置(X,Y)を渡し、
			キャレット位置を取得。 
      ドラッグ現在点としてフィールド変数endCaretPositionに設定。 
      ∙ このクラスのsetTextSelectionメソッドを呼ぶ 
      フィールド変数dragStartと
				dragEndの間をテキスト選択区間として設定する。
			 
       | 
    
    
      | 
      mouseClicked
       | 
      
      public void mouseClicked(MouseEvent e) 
      クリックした位置を現在のキャレット位置とし、フィールド変数caretPositionに設定する。 
      ∙ このクラスのgetCaretPositionAtMouseメソッドにマウス位置(X,Y)を渡し、キャレット位置を取得。 
      ∙ このクラスのsetTextSelectionメソッドを呼んでキャレット位置を設定する。 
      ∙ もし未確定テキストがあればリターン。
       | 
    
    
      | 
      mouseEntered
       | 
      
      public void mouseEntered(MouseEvent e) :何もしない。
       | 
    
    
      | 
      mouseExited
       | 
      
      public void mouseExited(MouseEvent e) :何もしない。
       | 
    
    
      | 
      mouseMoved
       | 
      
      public void mouseMoved(MouseEvent e) :何もしない。
       | 
    
    
      | 
      getCaretPositionAtMouse
       | 
      
      public CaretPosition getCaretPositionAtMouse(double X, double Y) 
      (X,Y)点が複数行のTextLayout配列の何処に属するかをCaretPositionで返す。 
      ∙ LineBreaker.getTextLayouts、
			getTextLayoutPositions、
			getBoundsを呼ぶ 
      複数行に対応するTextLayout配列(textLayouts)、各TextLayoutの位置を格納したPoint2D配列(positions)、
				各TextLayoutを囲むRectangle2D配列(bounds)を取得。 
      ∙ (X,Y)点を含むRectangle2D配列(bounds)の要素を見つけ、その配列indexをlineIndexに設定。 
      ∙ textLayouts[lineIndex]から、java.awt.font.TextHitInfo(java.awt.font.TextHitInfo)を取得。 
			これからtextLayouts[lineIndex]内での文字列位置positionInTextLayoutを得る。 
        int positionInTextLayout=hitInfo.getInsertionIndex();
			 
      ∙ lineIndexとpositionInTextLayoutからCaretPositionを取得し返す。 
      CaretPosition caret
				P=this.lineBreaker.getCaretPosition
				(lineIndex, positionInTextLayout); 
       | 
    
    
      | 
      setTextSelection
       | 
      
      public void setTextSelection(CaretPosition caretPos1, CaretPosition caretPos2, int ctrl) 
      引数: 
      caretPos1 - テキスト選択のドラッグ開始位置。 
      caretPos2 - テキスト選択のドラッグ終了位置。マウスをクリックしたときは、この引数にnullを指定する。 
      ctrl - Shift/Ctrlを押しながらマウスをクリックしたとき ctrl は 1/2。 
      処理: 
      caretPos1, caretPos2はドラッグ開始点と現在点のCaretPosition。 
      ∙ マウスがクリックされ (caretPos2=null)、 ctrl=0ならば、caretPos1 を現在のマウス位置
			(caretPosition)にセットする。 
       this.caretPosition = CaretPosition.getCaretPosition(mouseP1.getLineIndex(),
          mouseP1.getColumnIndex(), true, this.lineBreaker, "setTextSelection"); 
			  
      ∙ マウスがクリックされ (caretPos2=null)、 ctrl>0ならば、
			caretPositionと caretPos1.の間のテキストを選択する。 
      ∙ caretPos1, caretPos2ともにnullでは無いとき、次のように処理する。 
      通常、caretPos1, caretPos2をthis.selStartとthis.selEndに設定する。
				しかし文字列を選択する時に、マウスを文字列の後方から前方に動かすと、
				this.selStartとthis.selEndの順序は逆転するので、
				caretPos1, caretPos2の順序をチェックして逆転を防止する。 
				またcaretPos1, caretPos2が同じ位置を指しているときは、
				テキストの選択ではなくてmouseClickedの場合と同様、キャレットの位置を指定したと見なす。
				いずれの場合もFontStyle.setFontStyleToMenuメソッドで、
				選択またはクリックされたテキストの属性をメニューに反映させる。
			 
       | 
    
    
      | 
      displayMousePosition
       | 
      
      private void displayMousePosition(String mouseAction, double X, doubleY) 
      画面の下のパネルの2行目にTextBoxでのマウスの位置情報を表示する。キャレット位置、
			テキスト選択start,endの表示。
       | 
    
    
      | 
      contain
       | 
      
      private int contain(int iX, int iY) 
      (iX,iY)点がテキスト領域に入っているときtrueを返す。
       | 
    
    
      | resetCaret | 
      
      public void resetCaret() 
      現在のキャレット位置を解除する。
			フィールド変数caretPositionに(new CaretPosition(0, 0, 0, true))オブジェクトを設定。
       | 
    
    
      | resetSelection | 
      
      public void resetSelection() 
      テキスト選択を解除する。フィールド変数selStart, selEndにCaretPositionオブジェクトを設定する。
       | 
    
    
      | 
      clone
       | 
      
      public Object clone() 
      このオブジェクトのクローンを返す。
       |