Package jcurses.widgets

Source Code of jcurses.widgets.TextComponent

package jcurses.widgets;


import java.util.ArrayList;
import java.util.List;

import jcurses.event.ValueChangedEvent;
import jcurses.event.ValueChangedListener;
import jcurses.event.ValueChangedListenerManager;
import jcurses.system.CharColor;
import jcurses.system.InputChar;
import jcurses.system.Toolkit;
import jcurses.util.Paging;
import jcurses.util.Rectangle;

/**
*  The class is the superclass for text editing widgets
*/
public class TextComponent extends Widget {
 
  private int _width = 0;
  private int _height = 0;
 
  private int _cursPosX  =  0;
  private int _cursPosY   =   0;
 
  private int _firstChar = 0;
  private int _firstLine = 0;
 
 
 
  StringBuffer _text = new StringBuffer("");
  List<Integer> _lines = new ArrayList<Integer>();
  List<Integer> _lineLengths = new ArrayList<Integer>();
 
  /**
  *  The constructor
    *
    * @param width the preferred width of the component. If -1 is stated,
    * there is no preferred width and the component is layouted dependend on the
    * container and the text
    *  @param height the preferred height of the component. If -1 is stated,
    * there is no preferred width and the component is layouted dependend on the
    * container.
    * @text the initial text, if <code>null<code> the component is empty
    *
  */
 
  public TextComponent(int width, int height, String text) {
    _width = width;
    _height = height;
    setText(text);
   
  }
 
 
  /**
  *  The constructor
    *
    * @param width the preferred width of the component. If -1 is stated,
    * there is no preferred width and the component is layouted dependend on the
    * container and the text
    *  @param height the preferred height of the component. If -1 is stated,
    * there is no preferred width and the component is layouted dependend on the
    * container and the text.
    *
  */
  public  TextComponent(int width, int height) {
    this(width, height,"");
  }
 
  /**
  *  Constructor with no arguments. No preferred width and height, empty.
  */
 
  public  TextComponent() {
    this(-1, -1,"");
  }
 
 
  /**
  *  Konstruktor, nur Text, h�he und Breite vom Container bestimmt
  */
 
  public  TextComponent(String text) {
    this(-1, -1, text);
  }
 
  /**
  *  @return preferred width
  */
  protected int getWidth() {
    return _width;
  }
 
 
    /**
    *  @return preferred height
    */
  protected int getHeight() {
    return _height;
  }
 
  /**
  *  Sets the conteined text
    *
    * @param text text to set
  */
 
  public void setText(String text) {
    setText(text, true);
  }
 
    /**
    *  Sets the contained text
    * @param text text to set
    * @param dispatchEvent if true, the widget is repainted
    */
  public void setText(String text, boolean dispatchEvent) {
    text = (text == null)?"":text;
    _text = new StringBuffer(text);
    updateText(dispatchEvent);
    reset();
   
  }
 
  private void reset() {
    _cursPosX = 0;
    _cursPosY = 0;
    _firstChar = 0;
    _firstLine = 0;
  }
 
 
    /**
    * @return contained text
    */
  public String getText() {
    return _text.toString();
  }
 
 
  private void updateText() {
    updateText(true);
  }
 
  /**
  * F�r abgeleitete Klassen Textbreite und H�he und Koordinaten der oberen Rechten Ecke
  * des Sichtbaren Bereiches
  */
 
  protected int getTextX() {
    return _firstChar;
  }
 
 
  protected int getTextY() {
    return _firstLine;
  }
 
 
  protected int getTextHeight() {
    return _lines.size();
  }
 
 
  protected int getTextWidth() {
    int result = 0;
   
    for (int i=0; i<_lineLengths.size(); i++) {
      int value = ((Integer)_lineLengths.get(i)).intValue();
      if (value > result) {
        result = value;
      }
    }
   
    return result;
  }
 
 
 
 
  private void updateText(boolean dispatchEvent) {
   
   
   
    //neu darstellen
   
     _lines.clear()
     _lineLengths.clear();
    
     String text = _text.toString();
    
    
     int pos = 0;
   
     while (text.indexOf("\n",pos)!=-1) {
         _lines.add(new Integer(pos));
      _lineLengths.add(new Integer(text.indexOf("\n",pos)-pos));
      pos = text.indexOf("\n",pos)+1;
     }
    
     if (pos < text.length()) {
        _lines.add(new Integer(pos));
     _lineLengths.add(new Integer(_text.length()-pos));
     }
    
    
     if (_lines.size() == 0) {
         _lines.add(new Integer(0));
      _lineLengths.add(new Integer(0));
     } else {
        if (text.endsWith("\n")) {
       _lines.add(new Integer(text.length()));
      _lineLengths.add(new Integer(0));
     }
     }
    
     //event abschicken
   
    if (dispatchEvent) {
      _listenerManager.handleEvent(new ValueChangedEvent(this));
    }
    
    
  }
 
 
  /**
  *  This method draws text-dependent additional things such as scrollbars.
  * As default it makes nothing, can be overriden in inherited classes ( for example text area)
  */
  protected void drawAdditionalThings() {
    //nothing
  }
 
 
  /**
  *  This method refreshes text-dependent additional after a text change such as scrollbars.
  * As default it makes nothing, can be overriden in inherited classes ( for example text area)
  */
  protected void refreshAdditionalThings() {
    //nothing
  }
 
 
  /**
  * The method returns the rectangle, within that the text is painted.
    * Is overrided by derived classes for example to implement a border.
    *
  */
 
  protected Rectangle getTextRectangle() {
    Rectangle result =  getSize();
    result.setLocation(getAbsoluteX(), getAbsoluteY());
    result.setHeight(result.getHeight());
    return result;
  }
 
 
  private int getVisibleHeight() {
    return getTextRectangle().getHeight();
  }
 
 
  private Rectangle getTextRectangle(int firstLine) {
     Rectangle rect = getTextRectangle();
     int y = ((firstLine - _firstLine)>=0)?(firstLine - _firstLine):0;
     rect.setLocation(rect.getX(), rect.getY()+y);
     rect.setHeight(rect.getHeight()-y);
     return rect;
  }
 
 
  private Rectangle getLineRectangle(int firstLine) {
     Rectangle rect = getTextRectangle();
     int y = ((firstLine - _firstLine)>=0)?(firstLine - _firstLine):0;
     rect.setLocation(rect.getX(), rect.getY()+y);
     rect.setHeight(1);
     return rect;
  }
 
 
 
  private int getFirstLineNumber() {
      /*int result = _cursPosY - getTextRectangle().getHeight()+1;
    result = (result < 0)?0:result;*/
    return _firstLine;
  }
 
 
  private int getFirstCharNumber() {
    /*int result =  _cursPosX - getTextRectangle().getWidth()+1;
    result = (result < 0)?0:result;*/
    return _firstChar;
  }


  private static CharColor __textComponentDefaultColors = new CharColor(CharColor.MAGENTA, CharColor.BLACK);
 
  public CharColor getDefaultColors() {
    return __textComponentDefaultColors;
  }
 
 
 
  private static CharColor __focusedTextComponentDefaultColors = new CharColor(CharColor.BLUE, CharColor.WHITE, CharColor.REVERSE);
  private CharColor _focusedTextComponentColors = getFocusedTextComponentDefaultColors();
 
 
  public CharColor getFocusedTextComponentDefaultColors() {
    return __focusedTextComponentDefaultColors;
  }
 
 
  public CharColor getFocusedTextComponentColors() {
    return _focusedTextComponentColors;
  }
 
 
  public void setTextComponentColors(CharColor colors) {
    _focusedTextComponentColors = colors;
  }
 
 
  private static CharColor __cursorDefaultColors = new CharColor(CharColor.BLACK, CharColor.WHITE);
  private CharColor _cursorColors = getCursorDefaultColors();
 
 
  public CharColor getCursorDefaultColors() {
    return __cursorDefaultColors;
  }
 
 
  public CharColor getCursorColors() {
    return _cursorColors;
  }
 
 
  public void setCursorColors(CharColor colors) {
    _cursorColors = colors;
  }
 
 
  /**
  *  Aus Widget
  */
  protected Rectangle getPreferredSize() {
    return new Rectangle(_width, _height);
  }
 
 
  private void drawCursor() {
    char c = getCharacterAtCursorPosition();
    drawChar(_cursPosX,_cursPosY, getCursorColors(),c);   
  }
 
 
  private void drawChar(int x, int y, CharColor colors, char c) {
    int x1 = x-_firstChar;
    int y1 = y - _firstLine;
    String toPrint = (c == 0)?" ":replaceTextLineForPrinting(""+c);
    Toolkit.printString(toPrint,getTextRectangle().getX()+x1, getTextRectangle().getY()+y1,colors);
  }
 
 
  private void drawText(int index) {
    int firstLine = getFirstLineNumber();
    int begin = (firstLine > index)?firstLine:index;
   
      for (int i=begin; i<_lines.size(); i++) {
      drawLine(i);
    }
 
  }
 
 
  private void drawLine(int index) {
    Rectangle rect = getTextRectangle();
    CharColor colors = hasFocus()?getFocusedTextComponentColors():getColors();
    int firstLine = getFirstLineNumber();
    int firstChar = getFirstCharNumber();
    int pos = ((Integer)_lines.get(index)).intValue();
    int length = ((Integer)_lineLengths.get(index)).intValue();
    if ((firstChar < length) && ((index-firstLine) < rect.getHeight())) {
      int length2 = length - firstChar;
      int length3 = (length2 > rect.getWidth())?rect.getWidth():length2;
      Toolkit.printString(replaceTextLineForPrinting(_text.substring(pos+firstChar, pos+firstChar+length3)), rect.getX(), rect.getY()+index-firstLine, colors);
    }
  }
 
 
  private String getLine(int index) {
    if (index > _lines.size()) {
      return null;
    } else {
      int pos = ((Integer)_lines.get(index)).intValue();
      int length = ((Integer)_lineLengths.get(index)).intValue();
     
      return _text.substring(pos,pos+length);
    }
  }
 
 
  private void drawText() {
    drawText(0);
  }
 
  //Paging
 
 
  private Paging getPaging() {
    return new Paging(getVisibleHeight(), getTextHeight());
  }
 
  private int getPageNumber(int index) {
     return getPaging().getPageNumber(index);
    }
 
 
  private int getPageSize() {
    return getPaging().getPageSize();
  }
 
  private int getCurrentPageNumber() {
    return getPageNumber(_cursPosY);
  }
 
 
  int getPageStartIndex(int pageNumber) {
    return getPaging().getPageStartIndex(pageNumber);
  }
 
 
  int getPageEndIndex(int pageNumber) {
    return getPaging().getPageEndIndex(pageNumber);
  }

  int getCurrentPageOffset() {
    return getPaging().getPageOffset(_cursPosY);
    }
 
 
  private void drawBox(Rectangle rect) {
    CharColor colors = hasFocus()?getFocusedTextComponentColors():getColors();
    Toolkit.drawRectangle(rect, colors);
  }
 
 
  private void drawBox() {
    drawBox(getTextRectangle());
  }
 
 
  private void changeColors() {
    Rectangle rect = getTextRectangle();
    CharColor colors = hasFocus()?getFocusedTextComponentColors():getColors();
    Toolkit.changeColors(rect, colors);
  }
 
 
 
  protected void doPaint() {
    drawBox();
    drawText();
    if (hasFocus()) {
      drawCursor();
    }
  }
 
 
  protected boolean isFocusable() {
    return true;
  }
 
 
  protected void doRepaint() {
    doPaint();
  }
 
 
 
  private char getCharacterAtCursorPosition() {
    char result = 0;
    if (_text.length() > 0) {
      String line = (String)getLine(_cursPosY);
      if (_cursPosX < line.length()) {
        result = line.charAt(_cursPosX);
      } else {
        result = 0;
      }
    }
    return result;
  }
 
 
 
  private boolean isTextChanged(int x, int y) {
    return !((_firstChar == x) && (_firstLine == y));
  }
 
 
  private boolean isCursorChanged(int x, int y) {
    return !((_cursPosX == x) && (_cursPosY == y));
  }
 
 
  private void redrawAfterCursorMove(int bCursorPosX, int bCursorPosY, int bFirstChar, int bFirstLine, char bChar) {
    if (isTextChanged(bFirstChar, bFirstLine)) {
      paint();
    } else if (isCursorChanged(bCursorPosX, bCursorPosY)) {
       redrawOldChar( bCursorPosX, bCursorPosY, bChar);
          drawCursor();
    }
  }
 
 
  private void redrawOldChar(int bCursorPosX, int bCursorPosY,char bChar) {
    CharColor colors = hasFocus()?getFocusedTextComponentColors():getColors();
    drawChar(bCursorPosX,bCursorPosY,colors,bChar);
    
  }
 
 
  private void redrawAfterTextChange(int bCursorPosX, int bCursorPosY, int bFirstChar, int bFirstLine) {
    if (isTextChanged(bFirstChar, bFirstLine)) {
       paint();
    } else if (isCursorChanged(bCursorPosX, bCursorPosY)) {
    int y = Math.min(_cursPosY,bCursorPosY);
      drawBox(getTextRectangle(y));
    drawText(y);
    drawCursor();
      refreshAdditionalThings();
    }
   
  }
 
 
  private void redrawLine(int index) {
    drawBox(getLineRectangle(index));
    drawLine(index);
    drawCursor();
    refreshAdditionalThings();
  }
 
 
  /**
  *  This method replaces a line of text to printing througth another text line.
  *  This can be overrided in derived classes for example for painting all chars as capitals,
    * or for password input. Here the same line is returned.
    *
  * @param line a text line to replace, contains no line breaks
  * @return decoded line
  */
 
  protected String replaceTextLineForPrinting(String line) {
    return line;
  }
 
 
 
  protected boolean handleInput(InputChar ch) {
   
    int bCursorPosX = _cursPosX;
    int bCursorPosY = _cursPosY;
    int bFirstChar =  _firstChar;
    int bFirstLine =  _firstLine;
    char bChar = getCharacterAtCursorPosition();
     
   
    if (ch.getCode() == InputChar.KEY_RIGHT) {
      setCursorLocation(_cursPosX+1, _cursPosY);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_LEFT) {
      setCursorLocation(_cursPosX-1, _cursPosY);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_UP) {
      setCursorLocation(_cursPosX, _cursPosY-1);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_DOWN) {
      setCursorLocation(_cursPosX, _cursPosY+1);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_HOME) {
      setCursorLocation(_cursPosX, 0);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_END) {
      setCursorLocation(_cursPosX, getTextHeight()-1);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_NPAGE) {
      int newYPos = 0;
      if (getCurrentPageNumber() < (getPageSize()-1)) {
        newYPos = getPaging().getIndexByPageOffset(getCurrentPageNumber()+1,getCurrentPageOffset());
      } else {
        newYPos = getTextHeight()-1;
      }
      setCursorLocation(_cursPosX, newYPos, true);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
      return true;
    } else if (ch.getCode() == InputChar.KEY_PPAGE) {
      int newYPos = 0;
      if (getCurrentPageNumber() > 0) {
        newYPos = getPaging().getIndexByPageOffset(getCurrentPageNumber()-1,getCurrentPageOffset());
      } else {
        newYPos = 0;
      }
      setCursorLocation(_cursPosX, newYPos, true);
      redrawAfterCursorMove(bCursorPosX,bCursorPosY,bFirstChar,bFirstLine,bChar);
    } else if (ch.getCode() == InputChar.KEY_BACKSPACE) {
      deleteCharBeforeCursorLocation();
      if (_cursPosX == 0) {
        if (_cursPosY > 0) {
        int y = _cursPosY-1;
        if (y<0) {
          y=0;
        }
        int x = ((Integer) _lineLengths.get(y)).intValue();
          setCursorLocation(x,y);
        redrawAfterTextChange(bCursorPosX, bCursorPosY, bFirstChar, bFirstLine);
      }
      } else {
        setCursorLocation(_cursPosX-1, _cursPosY);
        redrawLine(_cursPosY);
      }
    
      return true;
    } else if (!ch.isSpecialCode()) {
      char c =  ch.getCharacter();
      insertCharAtCursorLocation(c);
      if ( c == '\n') {
        setCursorLocation(0, _cursPosY+1);
          redrawAfterTextChange(bCursorPosX, bCursorPosY, bFirstChar, bFirstLine);
      } else {
        setCursorLocation(_cursPosX+1, _cursPosY);
        redrawLine(_cursPosY);
      }
      return true;
    }
   
    return false;
  }
 
  /**
  *  Aus Widget
  */
 
  protected void focus() {
     changeColors();
    drawCursor();
  }
 
 
  protected void unfocus() {
    changeColors();
    redrawOldChar(_cursPosX,_cursPosY,getCharacterAtCursorPosition());
   
  }
 
 
 
 
 
 
  /**
  *  The method sets the cursor position to given koordinates ( within the text, not widget )
  * 
  *  @param x new x cursor coordinate within the text
  *  @param y new y cursor coordinate within the text
  */
  public void setCursorLocation(int x, int y) {
    setCursorLocation(x, y, false);
  }
 
  private void setCursorLocation(int x, int y, boolean pageAlignment) {
    if (y < 0) {
      _cursPosY = 0;
    } else if (y >= _lines.size()) {
      _cursPosY = _lines.size()-1;
    } else {
      _cursPosY = y;
    }

   
    int length = ((Integer)_lineLengths.get(_cursPosY)).intValue();
   
    if (x < 0) {
      _cursPosX = 0;
    } else if (x >= length) {
      _cursPosX = length;
    } else {
      _cursPosX = x;
    }
   
    _cursPosY = (_cursPosY < 0)?0:_cursPosY;
   
    // first Position
   
    if (_firstChar > _cursPosX) {
      _firstChar = _cursPosX;
    } else if (_firstChar < (_cursPosX-getTextRectangle().getWidth()+1)) {
      _firstChar = (_cursPosX-getTextRectangle().getWidth()+1);
    }
   
    if (pageAlignment) {
      _firstLine = getPageStartIndex(getPageNumber(_cursPosY));
    } else {
      if (_firstLine > _cursPosY) {
        _firstLine = _cursPosY;
      } else if (_firstLine < (_cursPosY-getTextRectangle().getHeight()+1)) {
        _firstLine = (_cursPosY-getTextRectangle().getHeight()+1);
      }
    }
   
   
   
  }
 
 
  private void insertCharAtCursorLocation(char c) {
    int pos = ((Integer)_lines.get(_cursPosY)).intValue()+_cursPosX;
    _text.insert(pos, c);
    updateText();
  }
 
 
  private void deleteCharBeforeCursorLocation() {
    int pos = ((Integer)_lines.get(_cursPosY)).intValue()+_cursPosX;
    if (pos > 0) {
      _text.deleteCharAt(pos-1);
    }
    updateText();
  }
 
 
//   private static String escapeString(String text) {
//     StringBuffer buf = new StringBuffer();
//     for (int i=0; i<text.length(); i++) {
//       char c = text.charAt(i);
//      if (c == '\n') {
//        buf.append("\\n");
//      } else if (c == '\r') {
//        buf.append("\\r");
//      } else if (c == '\t') {
//        buf.append("\\t");
//      } else  {
//        buf.append(c);
//      }
//     
//     }
//    
//     return buf.toString();
//  
//   }
  
  
   //Listener
  
  private ValueChangedListenerManager _listenerManager = new ValueChangedListenerManager();
  
  
  public void addListener(ValueChangedListener listener) {
    _listenerManager.addListener(listener);
  }
 
 
  public void removeListener(ValueChangedListener listener) {
      _listenerManager.removeListener(listener);
  }
 
 
 
 
 
 
 
 
 
 
 

}
TOP

Related Classes of jcurses.widgets.TextComponent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.