| 
      Summary: This page describes a simple text editor which enable us to input
      text in a text box, edit the text, add text attributes (bold, italic,
      fomt family, size color etc.) on the text and so on.
		 | 
	 
	
		| Classes on this page: TextBox, TextUndoSetup | 
	 
 
 =>
DrawTest: Text Editor using the Input Method Framework  
 
1. Overview 
1.1 Input Method Framework, Java 2D Graphics 
It seemed easy to build a text editor for a drawing tool using a Swing
component like JTextComponent or JEditorPane , however a text box created
by using a Swing component seemed impossible to be zoomed at any magnification.
As the result, we built a simple text editor using java awt, text and the
Input Method Framework. 
 
∙ Input Method Framework 
( =>
Java™ Input Method Framework (IMF) Technology) 
The keyTyped method of the java.awt.event.KeyListener receives alphabetic
text.  If input text is Japanese, the inputMethodTextChanged method
of the java.awt.event.InputMethodListener receives the text converted by
a kana-kanji converter. 
 
∙ AWT 
The AWT (java.awt) classes are used to display attributed strings
(java.text.AttributedString). Especially the related processing to the
java.awt.font.LineBreakMeasurer are important. 
 
1.2 Inputting text. 
(1) Operation 
 To input text to a text box, the inside of the text box must be clicked
by the mouse. After that, the text box will be selected and displayed with
a green frame which shows that the text box is editable. If a gray frame
is displayed in the text box, it is selected but not editable. 
 =>
	User's guide 
	Editing text 
The way of inputting text is the same as usual word processors. To input
Japanese text, a Kana-kanji converter is used. After alphabetic characters
have been input, they are converted to a kana/kanji and displayed with
a dotted underline. If the converted kana/kanji is not appropriate, a list
of candidate kana/kanji will be displayed by pressing conversion key or
space key. The correct kana/kanji can be selected by moving the cursor
or specifying the number.  
(2) Text input method 
When alphabetic characters are input, 
	the keyTyped method of the 
	ListenerPanel receives them and transfers them to 
	keyTyped method of TextBox. 
	When Japanese kana/kanji are input, 
	the inputMethodTextChanged method of the 
	ListenerPanel receives them by the InputMethodEvent and transfers them to 
	inputMethodTextChanged method of 
	TextBox. 
   
∙ The keyTyped method of theTextBox: Inserts characters to the 
CommittedTextContainer by the 
insertText method. 
 
∙ The inputMethodTextChanged method of theTextBox: 
If the committed text exists in the InputMethodEvent, it will be stored
to the CommittedTextContainer by the 
insertText method.  
If the composed text exists in the InputMethodEvent, it will be combined
with the committed text in the CommittedTextContainer, 
and the combined (composite) text will be displayed on the canvas.
  
 : 
Composed text and committed text  
Composed text - The possible text which can be converted from input alphabetic
characters by the input method (Kana-kanji converter). 
Committed text - The determinate text which was converted from input alphabetic
characters. 
 
	  
Figure 1 The procedure of inputting text
 
 
1.3 Setting a font styles to the input text and the Font menu on the toolbar   
  
2. Class TextBox
	return=>page top 
	 public class TextBox implements MouseListener, MouseMotionListener
  
 
  
    
      | 
     Method
       | 
      
      Description
       | 
     
    
      | 
      Constructor
       | 
      
      public TextBox () 
      Calls requestFocus method of the ListenerPanel.
       | 
     
    
      | getShapeContainer | 
      
      public ShapeContainer getShapeContainer() 
      Returns the shapeContainer field.
       | 
     
    
      | setShapeContainer | 
      
      public void setShapeContainer(ShapeContainer container) 
      Sets the parameter to the shapeContainer field.
       | 
     
    
      | 
      activateMouseListener
       | 
      
      public void activateMouseListener(boolean activate) 
      Parameters: 
      activate - If true, then this method makes this text box editable,
      otherwise uneditable. 
      Processing: 
      This method is called from the makeTextBoxEditable method. 
      ∙ If the activate is true, then performs the following. 
      Registers this object (TextBox) to the ListenerPanel 
				as a MouseListener and MouseMotionListener, 
        listenerPanel.addMouseListener(this); 
        listenerPanel.addMouseListener(this); 
      ∙ If the activate is false, then performs the following. 
      Removes this object from the ListenerPanel. 
        listenerPanel.removeMouseListener(this); 
        listenerPanel.removeMouseMotionListener(this);
				 
       | 
     
    
      | 
      isEditable
       | 
      
      public boolean isEditable 
      If this text box is editable, returns true.
       | 
     
    
      | 
      getBoundingBox
       | 
      
      public Rectangle2D getBoundingBox() 
      Returns the bounding box of this text box.
       | 
     
    
      | getTextArea | 
      
      public Rectangle2D getTextArea() 
      Returns the textArea field.
       | 
     
    
      | 
      setTextArea
       | 
      
      public void setTextArea(Rectangle2D textArea) 
      Sets the parameter to the textArea field.
       | 
     
        
          | getMarginlessTextArea | 
          public Rectangle2D getMarginlessTextArea() 
          Returns the rectangle area which is gotten by subtracting the textBoxInsets from the textArea. | 
         
        
          | getTextLayoutArea | 
          public Rectangle2D getTextLayoutArea() 
          Gets the array of the bounding rectangles covering text
          lines by the LineBreaker.getBounds method and returns the maximum rectangle which covers all the bounding
          rectangles.  | 
         
        
      
      getCommittedTextContainer 
       | 
      
      public CommittedTextContainer getCommittedTextContainer() 
      Returns the committedTextContainer.
       | 
     
    
      | 
      isCommittedText
       | 
      
      public boolean isCommittedText() 
      If the committed text isn't null, returns true.
       | 
     
    
      | getTextLocation | 
      
      public Rectangle getTextLocation() 
      This method is called from the ListenerPanel.getTextLocation method. 
      Returns the returned value of the LineBreaker.getCaretRectangle method. 
       : 
			The ListenerPanel.getTextLocation method 
			is defined by the InputMethodRequests interface.
       | 
     
    
      | 
      resizeTextArea
       | 
      
      public void resizeTextArea(Rectangle2D oldBox, Rectangle2D newBox) 
      This method is called by the ShapeElement.moveResize method 
			and it calls the setTextArea method.
       | 
     
    
      | 
      getTextBoxInsets
       | 
      
      public Insets getTextBoxInsets() 
      Returns the textBoxInsets field.
       | 
     
    
      | 
      setTextBoxInsets
       | 
      
      public void setTextBoxInsets(Insets insets) 
      Sets the parameter to the textBoxInsets field.
       | 
     
    
      | 
      getTextLineSpace
       | 
      
      public int getTextLineSpace() 
      Returns the lineSpace field.
       | 
     
    
      | 
      setTextLineSpace
       | 
      
      public void setTextLineSpace(double lineSpace) 
      Sets the parameter to the lineSpace field.
       | 
     
    
      | getTextAlign | 
      
      public int getTextAlign() 
      Returns the textAlign field.
       | 
     
    
      
      setTextAlign 
       | 
      
      public void setTextAlign(int textAlign) 
      Sets the parameter to the textAlign field.
       | 
     
    
      | setTextBoxLayout | 
      
      public void setTextBoxLayout(Insets textBoxInsets, int textAlign, double
      lineSpace) 
      Sets the parameters to the textBoxInsets, 
			lineSpace and textAlign fields.  
       | 
     
    
      | 
      setFontStyle
       | 
      
      public void setFontStyle(FontStyle newFontStyle) 
      This method is called by the ExecCommandUtil.setFontStyle method 
			and sets the parameter to the committed text in the CommittedTextContainer. 
      If the selected text exists, then this method sets the parameter to the 
      selected text, otherwise sets the parameter to all the committed text.
       | 
     
        
          | getFontColors | 
          public Color[] getFontColors() 
          This method is called from the ShapeContainer.getColors method. 
          Returns all the colors as as the array which is used in the CommittedTextContainer objects. | 
         
        
      
      getRealTextArea 
       | 
      
      public Rectangle2D getRealTextArea() 
      Returns the rectangle which is made from the textArea 
			excluding the area of the textBoxInsets.
       | 
     
    
      | getSerializableTextBox | 
      
      public SerializableTextBox getSerializableTextBox() 
      Returns the SerializableTextBox object. 
      This method is called from the UndoableDrawEdit.ChangeTextBox.
       | 
     
    
      | setSerializableTextBox | 
      
      public void setSerializableTextBox(SerializableTextBox data) 
      Parameter: 
      data - The SerializableTextBox object. 
      Processing: 
      Sets the contents of the data to this text box. 
      This method is called from the UndoableDrawEdit.ChangeTextBox.
       | 
     
    
      | 
      toString
       | 
      
      public String toString() 
      Returns the string representing this object. | 
     
    
      | 
      setValidTextLayout
       | 
      
      private void setValidTextLayout(boolean valid) 
      Set the parameter to the validTextLayout field.
       | 
     
    
      | 
      keyTyped
       | 
      
      public void keyTyped(char keyChar) 
      Parameters: 
      keyChar - The input character. 
      Processing: 
      This method is called by the ListenerPanel.keyTyped method. 
      ∙ Calls the deleteSelectedText method to delete the selected text. 
         this.deleteSelectedText(TextBox.KEY_BOARD);  
      ∙ Creates a new object of the AttributedString using the keyChar. 
         AttributedString attribChar=new AttributedString(String.valueOf(keyChar)); 
      ∙ Inserts the insertChar to the CommittedTextContainer. 
          this.insertText(TextBox.KEY_BOARD, insertionIndex, attribChar.getIterator()); 
      ∙ this.setValidTextLayout(false); 
       | 
     
    
      | 
      keyPressed
       | 
      
      public void keyTyped(int keyCode) 
      Parameters: 
      keyCode - The input character code. 
      Processing: 
      This method is called by the ListenerPanel.keyPressed method to move the text cursor (caret). 
      ∙ If the keyCode equals KeyEvent.VK_LEFT or KeyEvent.VK_RIGHT, the performs the following. 
       Calls the CaretPosition.columnOffset method to move the text cursor to leftward or rightward. 
      ∙ If the keyCode equals KeyEvent.VK_UP or KeyEvent.VK_DOWN, the performs the following. 
       Calls the CaretPosition.lineOffset method to move the text cursor to upward or downward. 
       =>
			ListenerPanel Key code in the KeyEvent  
       | 
     
    
      | 
      inputMethodTextChanged
       | 
      
      public void inputMethodTextChanged(InputMethodEvent event) 
      This is the method defined by the InputMethodListener of the InputMethod Frame Work. 
      This method receives the InputMethodEvent from the 
			ListenerPanel.inputMethodTextChanged method. 
      ∙ If this method received the committed text via the event, calls the insertText method. 
      ∙ If this method received the uncommitted text (composed text) via the event, performs the following. 
      Calls the deleteSelectedText method 
				to delete the selected text. 
				Sets the attribute of TextAttribute.INPUT_METHOD_HIGHLIGHT and the 
				currentFontStyle to the composed text 
				and sets it to the field of the composedTextIterator.
			  
			
       :
			The composedTextIterator is merged 
			to the committed text and displayed by the getDisplayText method. 
       =>
			Figure 1. The procedure of inputting text
       | 
     
    
      | 
      printInputMethodStatus
       | 
      
      private void printInputMethodStatus(InputMethodEvent event) 
      Prints the state of the inputMethodTextChanged method for debugging.
       | 
     
    
      | 
      insertText
       | 
      
				public void insertText(int method, int position, AttributedCharacterIterator attribStr) 
				Parameters: 
					method - KEY_BOARD, 
					INPUTMETHOD_TEXTCHANGED, 
					COMMAND or UNDO_REDO 
					position - The text insertion position. 
					attribStr - The text to be inserted. 
					Processing:
  
					
          (a) method ==TextBox.KEY_BOARD or TextBox.INPUTMETHOD_TEXTCHANGED 
          ∙ Gets the committedText from the CommittedTextContainer. 
          AttributedString committedText=this.committedTextContainer.getAttributedString();  
          ∙ Gets the FontStyle from the attributed character which is located 
						ahead of the specified  position in the committedText. 
          AttributedCharacterIterator iterator=committedText.getIterator(); 
					FontStyle fontStyleAt=FontStyle.getFontStyleAt(iterator, position); 
          if(!FontStyle.isDefaultFontStyle(fontStyleAt)) fontStyle=fontStyleAt;  
					 
          ∙ Sets the fontStyle to the attribStr. 
          insertStr = fontStyle.setTo(attribStr, 0, attribStr.getEndIndex());   
					
          (b) method ==TextBox.COMMAND 
          ∙ Checks whether a FontStyle object is set to the attribStr or not. 
          boolean isFontStyle=FontStyle.isFontStyle(attribStr, attribStr.getBeginIndex(), 
						attribStr.getEndIndex()) 
						 
          ∙ If not, gets the FontStyle from the attributed character which is located 
          ahead of the specified  position in the committedText and sets it to the attribStr.
  
					
          (c) Post process of the above (a) and (b) 
          ∙ Inserts the insertStr to the the CommittedTextContainer 
					by the CommittedTextContainer.insertText method. 
          this.committedTextContainer.insertText(insertionIndex, insertStr)  
          ∙ Gets the string (AttributedCharacterIterator) from the CommittedTextContainer 
					by the getDisplayText method and recreates the 
					LineBreaker object to breaks the string into lines. 
					∙ Updates the text cursor (caret) position by the CaretPosition.updateCaretPosition method. 
          ∙ Undo setup: if the parameter of the method doesn't equal UNDO_REDO, 
					then sets the undo setup by using the TextUndoSetup.InsertText object. 
					 
					
           : 
						All the text inputting operation uses this method because of the undo setup.
        | 
     
    
      | 
      deleteSelectedText
       | 
      
      private void deleteSelectedText(int method) 
      Parameters: 
      method - KEY_BOARD, 
			INPUTMETHOD_TEXTCHANGED, 
			COMMAND or UNDO_REDO  
      Processing: 
      Gets the start and end position of the selected text from the selStart, 
			selEnd fields and calls the deleteText method. 
       | 
     
    
      | 
      deleteText
       | 
      
      public void deleteText(int method, int start, int end) 
      Parameters: 
      method - KEY_BOARD, 
			INPUTMETHOD_TEXTCHANGED, 
			COMMAND or UNDO_REDO  
      start - The start position of the text to be deleted. 
      end - The end position of the text to be deleted. 
      Processing: 
      ∙ Deleting the text: deletes the text between the start and end by the 
			deleteText of the 
			CommittedTextContainer. 
      ∙ The cursor position: updates the text cursor (caret) position by
      the updateCaretPosition method of the 
			LineBreaker.  
      ∙ The selected text: clears the selected text by calling the resetSelection method. 
      ∙ Undo setup: if the parameter of the method doesn't equal UNDO_REDO, 
			then sets the undo setup by using the TextUndoSetup.DeleteText object. 
       : All the text deleting operation uses this method because of the undo
      setup. 
       | 
     
    
      
      deleteText 
          ByDelCommandOrBSkey
       | 
      
      public int deleteTextByDelCommandOrBSkey(int method) 
      Parameters: 
      method - KEY_BOARD, 
			INPUTMETHOD_TEXTCHANGED, 
			COMMAND or UNDO_REDO  
      Returns: 
      Returns the number of the deleted characters.  
      Processing: 
      This method is called by the delete of the Edit. 
      ∙ Deletes the selected text by the del command or Back space key. 
      Gets the start position and end position of the selected text by the 
				getSelectedTextStart and 
				getSelectedTextEnd method 
				and calls the deleteText method.
			 
      ∙ Deletes one character before the text cursor by Back space key. 
      Gets the text cursor position by the 
				CaretPosition.getTextIndex, 
				sets the start position and end position and calls the deleteText method. 
			 
       | 
     
    
      | replaceText | 
      
      public void replaceText(int method, AttributedString attribStr) 
      Parameters: 
      method - KEY_BOARD, 
			INPUTMETHOD_TEXTCHANGED, 
			COMMAND or UNDO_REDO  
      Processing: 
      This method is called by the undo and redo methods of the UndoableEdit.ChangeText. 
      This method replaces the committed text in the 
			CommittedTextContainer with the parameter of attribStr by calling 
			setCommittedText of the 
			CommittedTextContainer.
       | 
     
    
      | 
      getComposedText
       | 
      
      public AttributedCharacterIterator getComposedText() 
      Returns the committedTextIterator.
       | 
     
    
      | 
      getDisplayText
       | 
      
      public AttributedCharacterIterator getDisplayText() 
      Returns: 
      Returns the text to be displayed on the canvas.  
      Processing: 
      If the composed text doesn't exist (composedTextIterator 
			==null), then returns the committed text in the CommittedTextContainer.  
      If the composed text exists, then creates the composite text by calling
      the getDisplayText method of the 
			CommittedTextContainer and returns the composite text. 
       : 
			The composition of the committed text and uncommitted text is done by the
      createCompositeText of the 
			AttributedStringUtil.
       | 
     
    
      | 
      drawTextBox
       | 
      
      public void drawTextBox(Graphics g) 
      This method is the main method of drawing the text box and called by the
      drawShape of the ShapeContainer. 
			This method calls the following methods. 
      ∙ drawTextArea - Draws the frame of the text box. 
      ∙ drawText - Draws the committed text and the composed text. 
      ∙ drawCaret - Draws the text cursor (caret). 
      ∙ drawTextSelection - Draws the highlight over the selected text.
       | 
     
    
      | 
      drawTextArea
       | 
      
      public void drawTextArea(Graphics g) 
      If the text box is editable, the draw the frame with green, otherwise with light gray.
       | 
     
    
      | 
				drawText
       | 
      
				public void drawText(Graphics g) 
				Draws the text inside the text box.
  
				
				∙ If the validTextLayout is false, 
					then calls the LineBreaker object and recreates the text layout.
					 
				Updates the selStart, 
					selEnd and caretPosition fields 
					by the CaretPosition.updateCaretPosition method.
				  
				
				∙ Gets the array of the TextLayout objects by the 
					LineBreaker.getTextLayouts.
					 
				Each TextLayout object provides the graphical representation of an attributed
					string (AttributedCharacterIterator) which corresponds to each line.
				  
				
				∙ Gets the array of the TextLayout positions by the 
					LineBreaker.getTextLayoutPositions method.
					
  
					
				∙ Draws the TextLayout objects by the draw method of the TextLayout. 
				textLayouts[i].draw(g2, (float)positions[i].getX(), (float)positions[i].getY()) 
					 
						=> LineBreaker
				  
				∙ If DrawParameters.DRAW_TEXTLAYOUT is true, 
					draw java.awt.font.TextLayout bounds. 
					
						  
						Normal displaydraw TextLayout bounds
					 
       | 
     
    
      | 
      drawCaret
       | 
      
      public void drawCaret(Graphics g, int offset) 
      Parameters: 
      offset - The offset from the current text cursor (caret) position. The offset
      amount is the number of characters in uncommitted text. 
      Processing: 
      Draws the text cursor (caret) at the offset position from the current text
      cursor (caret) position. 
      Gets the rectangle representing the caret shape by calling the 
			LineBreaker.getCaretRectangle 
			with the offset and draw the rectangle on the canvas.
       | 
     
    
       | drawTextSelection | 
       
      public void drawTextSelection(Graphics g) 
      Draws the highlight over the selected text. The highlight should be drawn
      on the multiple lines, because the selected text exists over multiple lines. 
      ∙ Gets the start line index (startLine) and the last line index (endLine)
				of the highlight by the CaretPosition.getLineIndex method. 
				And gets the positions (startColumnIndex and endColumnIndex) of the highlight in the start line and the last line by the 
				CaretPosition.getColumnIndex method. 
      ∙ Gets the array of the TextLayout objects by the 
			LineBreaker.getTextLayouts method. 
      Gets the highlight shape as follow: 
         Shape highlight=textLayouts[i].getLogicalHighlightShape(start, end); 
          If i==startLine, then start=startColumnIndex . 
          If i==endLine, then end=endColumnIndex . 
          If startLine< i<endLine, then start=0 and end=(the number of the characters in the textLayouts[i]).
			 
      ∙ Draws the highlight. 
      if(highlight!=null) g2.fill(highlight); 
      ∙ Draws the TextLayout objects by the draw method of the TextLayout. 
        textLayouts[i].draw(g2, (float)positions[i].getX(), (float)positions[i].getY()); 
      This statement is to redraw the selected text because the selected text
      is overwritten by the highlight shape.
			 
       | 
     
    
      | getTextIndex | 
      
      public int gettextIndex() 
      Returns the caret (text cursor) position in the committed text.
       | 
     
    
      | hasSelectedText | 
      
      public boolean hasSelectedText() 
      Returns true if the selected text is exists. 
          This method is called from the Edit object, DialogOfShapeFormat object and so on. 
       | 
     
    
      | getSelectedTextStart | 
      
      public int getSelectedTextStart() 
      Returns the start position of the selected text.
       | 
     
    
      | getSelectedTextEnd | 
      
      public int getSelectedTextEnd() 
      Returns the end position of the selected text. | 
     
    
      | getSelectedText | 
      
      public AttributedString getSelectedText() 
      Returns the selected text. | 
     
    
      | 
				mousePressed | 
      
				public void mousePressed(MouseEvent e) 
				In the mousePressed, mouseDragged and mouseReleased methods, two operations	are performed. 
				The first operation is moving the text box boundary (User's Guide  
				move text box boundary). 
				The second operation is selecting text by dragging the mouse (User's Guide  
				selecting text). 
  
				
				(1)moving the text box boundary 
      ∙ Gets the current MousePositionInfo objects by 
			MousePositionLS.getAllMousePositionInfo. 
      If the mouse position code 
				of a MousePositionInfo object is TEXTBOX_BOUNDARY, then sets the MousePositionInfo object to the 
				mousePositionInfo field.
			 
      ∙ If the mousePositionInfo isn't null, performs the following. 
      
				・Set true to the modified field. 
        ・Creates a ConnectionUtil object 
					and calls the ConnectionUtil.setTargets method. 
        ・Calls the ContainerManager.undoSetupStart method.
			 
			 
			
      (2)selecting text
			
				If the uncommitted text exists (composedTextIterator!=null), 
				then outputs the warning message, otherwise gets the text cursor (caret) position by the 
				getCaretPositionAtMouse method 
				and sets the position to the dragStart.
			  
       | 
     
    
      | 
      mouseDragged
       | 
      
      public void mouseDragged(MouseEvent e)
  
			
      (1)moving the text box boundary
      ∙ Gets the boundary edge of this text box by the
      MousePositionInfo.getInformation method 
			and moves the edge by setting a new rectangle to the textArea field. 
      ∙ If the boundary edge is moved largely, resizes the shape element containing this text box
      by the ShapeElement.moveResize method. 
      If connectors are connected to the shape element, changes the connectors
      by the ConnectionUtil.resizeConnectors.
			 
  
			
      (2)selecting text
      ∙ If the uncommitted text exists (composedTextIterator!=null), 
			this method returns. 
      ∙ Gets the text cursor (caret) position by the 
			getCaretPositionAtMouse method 
			and calls the setTextSelection method 
			to specifies the interval of the selected text. 
       | 
     
    
      | mouseReleased | 
      
      public void mouseReleased(MouseEvent e)
			 
      (1)moving the text box boundary
      If the modified field is true, 
				set the changed code (UndoConstants.CONTAINER) to the ShapeContainer and 
				calls the ContainerManager.undoSetupEnd method.
			  
			
      (2)selecting text
      ∙ Gets the text cursor (caret) position by the 
			getCaretPositionAtMouse method and calls the 
			setTextSelection method to specifies the interval of the selected text.
       | 
     
    
      | mouseClicked | 
      
      public void mouseClicked(MouseEvent e) 
      ∙ Gets the text cursor (caret) position by the getCaretPositionAtMouse method 
			and calls the setTextSelection method to specifies the caret position.
       | 
     
    
      | 
      mouseEntered
       | 
      
				public void mouseEntered(MouseEvent e) 
      ⋅ Nothing is done.
       | 
     
    
      | 
      mouseExited
       | 
      
				public void mouseExited(MouseEvent e) 
      ⋅ Nothing is done.
       | 
     
    
      | mouseMoved | 
      
				public void mouseMoved(MouseEvent e) 
      ⋅ Nothing is done.
       | 
     
    
      | 
      getCaretPositionAtMouse
       | 
      
      public CaretPosition getCaretPositionAtMouse(double X, double Y) 
      Parameters: 
      X,Y - The mouse position. 
      Returns: 
      The text cursor (caret) position which corresponds to (X,Y). 
      Processing:  
      ∙ Calls the getTextLayouts, 
			getTextLayoutPositions and 
			getBounds methods of the 
			LineBreaker. 
      TextLayout[] textLayouts=this.lineBreaker.getTextLayouts(); 
      Point2D[] positions=this.lineBreaker.getTextLayoutPositions(); 
      Rectangle2D[] bounds=this.lineBreaker.getBounds(); 
      ∙ Finds of an element of the bounds which contains (X,Y) point. 
      Let's the index of the element as the lineIndex. 
      ∙ Gets the TextHitInfo object (hitInfo) by the java.awt.font.TextHitInfo
      method and the text cursor (caret) position (positionInTextLayout)
      in the textLayouts[lineIndex]. 
      TextHitInfo hitInfo=textLayouts[lineIndex].hitTestChar(clickX, clickY); 
      int positionInTextLayout=hitInfo.getInsertionIndex(); 
			 
      ∙ Gets the CaretPosition from the lineIndex and positionInTextLayout by
      using the LineBreaker.getCaretPosition. 
      CaretPosition caretP=
				this.lineBreaker.getCaretPosition
				(lineIndex, positionInTextLayout);
			 
       | 
     
    
      | setTextSelection
       | 
      
      public void setTextSelection(CaretPosition caretPos1, CaretPosition caretPos2, int ctrl) 
      Parameters: 
      caretPos1 - The first caret position for selecting text. 
      caretPos2 - The second caret position for selecting text. If the mouse was clicked,
      then the caretPos2 
       is null. 
      ctrl - The ctrl is 1/2, if the mouse was clicked with holding down Shift/Ctrl key. 
      Processing: 
      ∙ If the mouse was clicked (caretPos2=null) and ctrl equals 0, then sets caretPos1 to the 
			caretPosition. 
      this.caretPosition = CaretPosition.getCaretPosition(mouseP1.getLineIndex(),
          mouseP1.getColumnIndex(), true, this.lineBreaker, "setTextSelection"); 
			 
          ∙ If the mouse was clicked  (caretPos2=null) and ctrl equals 1/2, 
					then select the text between the caretPosition. and caretPos1. 
      ∙ If the mouse was dragged in the reverse direction, then performs the following. 
      If the mouse was dragged in the reverse direction such as from right to
      left in the same line or from lower line to upper line, then exchanges the caretPos1 and the caretPos2. 
      ∙ If the position of the caretPos1 equals to the position of the caretPos2, then performs the following. 
      In this case, the mouse dragging wasn't done substantially,
      so sets the caretPos1 to the caretPosition field (current caret position).
			 
      ∙ Calls the  FontStyle.setFontStyleToMenu method to reflect the attributes (font family, font size, bold, italic
      and so on) of the selected or clicked text on the appearance of the menu components on the tool bar. 
       | 
     
    
      | displayMousePosition | 
      
      private void displayMousePosition(String mouseAction, double X, double Y) 
      Displays the mouse position, caret position and the position of the selected
      text to the lower line of the status panel at the bottom of the window. 
       
       | 
     
    
      | contain | 
      
      private int contain(int iX, int iY) 
      Returns 1, if the point (iX,iY) is in the real text area given by
      the getRealTextArea method.
       | 
     
    
      | resetCaret | 
      
      public void resetCaret() 
      Sets (new CaretPosition(0, 0, 0, true))object to the field of the caretPosition.
       | 
     
    
      | resetSelection | 
      
      public void resetSelection() 
      Resets the selected text. 
        this.selStart=new CaretPosition(-1,-1); 
        this.selEnd=new CaretPosition(-1,-1);
       | 
     
    
      | 
      clone
       | 
      
      public Object clone() 
      Returns the clone of this object.
       | 
     
  
 
  
3. Class TextUndoSetup
return=>page top 
	If the undo and redo setting is done for each character, it will be uneconomical. 
	Therefore, if multiple characters are inserted or deleted without a break, 
	the undo and redo setting should be done for the block of the characters. 
  This object provides a convenient way to the undo and redo setting which can handles the block of the characters. 
	The methods of this class are called only by theinsertText method 
	and deleteText methods of the TextBox. 
 =>
The undo setup for each command
 
 
3.1 Nested class TextUndoSetup.InsertText
return=>page top 
This nested class is constructed based on the 
	UndoableDrawEdit.InsertText class. 
	If a new character is inserted after the previous one without a break, 
	then the character will be added to the UndoableDrawEdit.InsertText 
	object which was created when the first character was inserted. 
	If a new characters is inserted after some kind of a break or inserted to a different text box, 
	a new UndoableDrawEdit.InsertText object will be created 
	and the new character will be added to the new object.
 
 
  
    
      | 
      Method
       | 
      
      Description
       | 
     
    
      | 
      setInsertedText
       | 
      
      public void setInsertedText(ShapeContainer shapeContainer, AttributedString
          insString, int start, int end, boolean delimit) 
      Parameters: 
				shapeContainer - The shape object having a text box. 
				insString - The inserted string. 
				start - The start position of the inserted string. 
				end - The end position of the inserted string. 
				delmit - After inserting the insString, no string can be inserted to the current 
			UndoableDrawEdit.InsertText object. 
      Processing: 
      Sets the undo and redo for the inserted string. This method checks whether
      the undo and redo setting for the inserted string can be added to the 
			InsertText object or not. 
			If yes, then the undo and redo setting will be added to the 
			InsertText object.
       | 
     
    
      | 
      initialSet
       | 
      
      private void initialSet(ShapeContainer shapeContainer, AttributedString
      insString, int start) 
      Parameters: 
      Same as the setInsertedText method. 
      Processing: 
      If the undo and redo setting for the inserted string can't be added to the 
			InsertText object, 
			then this method performs the followings: 
      ∙ Creates a new object of the UndoableDrawEdit.InsertText 
			and sets it to the InsertText field. 
      ∙ Adds the InsertText object to the 
			undoDrawManager by the 
			addEdit method of the 
			UndoDrawManager. 
       | 
     
  
 
  
3.2 Nested class TextUndoSetup.DeleteText
return=>page top 
This nested class is constructed based on the 
	UndoableDrawEdit.DeleteText class. 
	The idea of this class is same as the nested class InsertText.
 
  
    
      | 
      Method
       | "
      
      Description
       | 
     
    
      | 
      setDeletedText
       | 
      
      public void setDeletedText(ShapeContainer shapeContainer, AttributedString
      delString, int start, int end) 
      Parameters: 
      shapeContainer - The shape object having a text box. 
      delString - The deleted string. 
      start - The start position of the deleted string. 
      end - The end position of the deleted string. 
      Processing: 
      Sets the undo and redo for the deleted string. This method checks whether
      the undo and redo setting for the deleted string can be added to the 
			DeletedText object or not. 
			If yes, then the undo and redo setting will be added to the 
			DeletedText object.
       | 
     
    
      
      initialSet 
       | 
      
      private void initialSet(ShapeContainer shapeContainer, AttributedString delString, int start) 
      Parameters: 
      Same as the setDeletedText method. 
      Processing: 
      If the undo and redo setting for the deleted string can't be added to the
      DeletedText object, then this method performs the followings: 
      ∙ Creates a new object of the UndoableDrawEdit.DeleteText and sets it to the DeletedText field. 
      ∙ Adds the DeletedText object to the undoDrawManager by the addEdit method of the UndoDrawManager. 
       | 
     
  
 
  
 |