⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textareacomposer.java

📁 开发j2me 手机程序必须的用到的。文件较小
💻 JAVA
字号:
package com.jmobilecore.ui.core;

import javax.microedition.lcdui.Font;
import java.util.Vector;

/**
 * The <code>TextAreaText</code> defines set of methods
 * that supports a text caret's handling and basic text editing.
 *
 * @author Evgeniy Krapiva
 * @author Greg Gridin
 */
public class TextAreaComposer implements AbstractComposer {
    /**
     * <code>LineRange</code> represents 2 numbers - ranges for displayed text
     */
    static public class LineRange {
        public int from;
        public int to;

        public LineRange(int from, int to) {
            this.from = from;
            this.to = to;
        }
    }

    /**
     * Current wrapping style
     */
    public byte wrappingStyle = TextArea.WORD_WRAPPING;

    /**
     * Current caret position in characters from the beginning of text
     */
    protected int caretPosition = 0;

    /**
     * Current caret position from the beginning of a row
     */
    protected int caretPositionX = 0;

    /**
     * The caret vertical position from the top of component
     */
    protected int caretPositionY = 0;

    /**
     * Holds the LineRange classes. Total number of rows the flat text
     * is splitted into equals linebreaks.size()
     */
    protected Vector linebreaks;

    /**
     * Current row where the caret is situated
     */
    protected LineRange currentRange;

    /**
     * The text to edit
     */
    protected StringBuffer text;

    /**
     * The number of rows
     */
    int nRows;

    /**
     * The work area width
     */
    int componentWidth;

    /**
     * The first of the visible rows
     */
    int startRow = 0;

    /**
     * Text font
     */
    private Font font;

    /**
     * Constructs new instance of <code>TextAreaText</code>.
     *
     * @param rows      the number of rows to display
     * @param compwidth
     * @param font      the current font
     */
    public TextAreaComposer(int rows, int compwidth, Font font) {
        text = new StringBuffer();
        linebreaks = new Vector();

        nRows = rows;
        componentWidth = compwidth;
        this.font = font;

        startRow = 0;
        caretPosition = 0;
        caretPositionX = 0;
        caretPositionY = 0;
        currentRange = new LineRange(0, 0);
    }

    /**
     * Splits the text onto displayable substrings
     */
    public void indexText() {
        final int length = text.length();

        linebreaks.removeAllElements();
        if (length == 0) return;

        if (wrappingStyle == TextArea.SYMBOL_WRAPPING) {
            String temp;
            int p = 0, oldp = 0;

            //start the splitting
            while (true) {
                oldp = p;
                do {
                    p++;
                    if (p > text.length()) break; //previous symbol was final
                    temp = text.toString().substring(oldp, p);
                } while (font.stringWidth(temp) <= componentWidth);

                addLine(oldp, p - 1); //add the substring

                if (p > text.length()) break; //if complete then exit

                p = p - 1;
            }
        } else if (wrappingStyle == TextArea.WORD_WRAPPING) {
            int start = 0, end = 0, lastSpace = -1;
            int curWidth = Style.H_GAP;
            char ch;

            for (int pos = 0; pos < length; pos++) {
                ch = text.charAt(pos);
                if (ch == '\n') {
                    addLine(start, pos);
                    curWidth = Style.H_GAP;
                    //text.setCharAt(pos,' ');
                    lastSpace = start = pos + 1;
                    continue;
                }
                if (ch == ' ') {
                    lastSpace = pos;
                    if (start == pos) {
                        start++;
                        continue;
                    }
                }
                curWidth += font.charWidth(ch);
                if (curWidth >= componentWidth) {
                    end = (lastSpace > start) ? lastSpace + 1 : pos;
                    addLine(start, end);
                    curWidth = Style.H_GAP;
                    lastSpace = start = end;
                    pos = end - 1;
                }
            }
            addLine(start, length);

        }
    }

    /**
     * Adds the line
     */
    private void addLine(int from, int to) {
        linebreaks.addElement(new LineRange(from, to));
    }

    /**
     * Moves the caret one position left
     *
     * @return <code>true</code> if the moving is possible/done, <code>false</code> otherwise
     */
    public boolean caretLeft() {
        return setCaretPosition(-1, 0);
    }

    /**
     * Moves the caret one position right
     *
     * @return <code>true</code> if the moving is possible/done, <code>false</code> otherwise
     */
    public boolean caretRight() {
        return setCaretPosition(1, 0);
    }

    /**
     * Moves the caret one position down
     *
     * @return <code>true</code> if the moving is possible/done, <code>false</code> otherwise
     */
    protected boolean caretDown() {
        return setCaretPosition(0, 1);
    }

    /**
     * Moves the caret one position up
     *
     * @return <code>true</code> if the moving is possible/done, <code>false</code> otherwise
     */
    protected boolean caretUp() {
        return setCaretPosition(0, -1);
    }

    /**
     * Moves the caret in horizontal and vertical directions
     *
     * @param hDirection the horizontal offset
     * @param vDirection the vertical offset
     * @return <code>true</code> if move is complete, <code>false</code> if move failed
     */
    private boolean setCaretPosition(int hDirection, int vDirection) {
        int size = linebreaks.size();

        //if caretLeft or CaretRight
        if (vDirection == 0) {
            caretPosition = caretPosition + hDirection;   //set new value of caretPosition

            if (caretPosition < 0) {
                caretPosition = 0;
                return false;
            }

            if (caretPosition > text.length()) {
                caretPosition = text.length();
                return false;
            }

            //lets locate the range where the caret is
            int r = findRange(caretPosition);
            if (r == -1) return false;

            currentRange = (LineRange) linebreaks.elementAt(r);

            //the caret can be on empty space after the final symbol in final substring only
            //in other cases caters moves to next line
            if (caretPosition == currentRange.to && r != size - 1)
                currentRange = (LineRange) linebreaks.elementAt(++r);

            //lets set caret offset from beginning of the line
            caretPositionX = caretPosition - currentRange.from;

            //if caret moves to next line then
            if (startRow + caretPositionY != r) {
                //add to caretPositionY the direction of caret offset
                caretPositionY += r - (startRow + caretPositionY);

                //if caret is located on following line then
                if (caretPositionY >= nRows) {
                    startRow++;   //start drawing from then next line
                    caretPositionY--;  //but caret stays on the last line
                }
                //if caret is located on preceding line then
                else if (caretPositionY < 0) {
                    if (startRow > 0) startRow--;  //start drawing from then previous line
                    caretPositionY++;  //but caret stays on the first line
                }

            } //end if


        } //end of caretLeft/caretRight processing


        //***************************************************************************************88

        //if caretUp, caretDown
        if (vDirection != 0 && size != 0) {
            //set new value of caretPosition
            caretPositionY = caretPositionY + vDirection;

            // if caretDown
            if (vDirection > 0) {
                //if cater is on the final line then it stays there
                if (caretPositionY + startRow >= size) {
                    caretPositionY--;
                    return true; //true to keep focus
                }

                //if caret moves to next screen
                if (caretPositionY >= nRows) {
                    startRow++;  //scroll
                    caretPositionY--;
                }

                //now we have new currentRange
                try {
                    currentRange = (LineRange) linebreaks.elementAt(startRow + caretPositionY);
                } catch (ArrayIndexOutOfBoundsException ex) {
                    return false;
                }

            }

            //if caretUp
            if (vDirection < 0) {
                //if cater is on the first line then it stays there
                if (caretPositionY < 0) {
                    if (startRow > 0) startRow--;
                    caretPositionY = 0;
                }

                try {
                    currentRange = (LineRange) linebreaks.elementAt(startRow + caretPositionY);
                } catch (ArrayIndexOutOfBoundsException ex) {
                    return false;
                }
            }

            //if caret position is greater than substring length
            if (currentRange.from + caretPositionX > currentRange.to) {
                caretPosition = currentRange.to - 1; //put the caret to end of the substring
                caretPositionX = currentRange.to - currentRange.from - 1;
            } else
                caretPosition = currentRange.from + caretPositionX;
        }

        return true;
    }


    /**
     * Deletes previous symbol, moves cursor one position left
     *
     * @return <code>true</code> if the delete and moving is possible/done, <code>false</code> otherwise
     */
    public boolean backspace() {

        if (!caretLeft()) return false;
        return deleteChar();
    }

    /**
     * Deletes current symbol
     *
     * @return <code>true</code> if the delete possible/done, <code>false</code> otherwise
     */
    public boolean deleteChar() {
        if (caretPosition < 0) return false;
        if (caretPosition >= text.length()) return false;

        text.deleteCharAt(caretPosition);

        //if last symbol is deleted then moves caret back
        if (currentRange.to - currentRange.from == 1) caretLeft();

        indexText();

        setCaretPosition(0, 0);
        return true;
    }

    /**
     * Adds new symbol or replaces the current one
     *
     * @param ch         new symbol
     * @param insertMode if <code>true</code> then new symbol will be added, otherwise the current symbol
     *                   will be replaced
     * @return <code>true</code> if the add/replace is possible, <code>false</code> otherwise
     */
    public boolean addChar(char ch, boolean insertMode) {

        if (caretPosition < 0) caretPosition = 0;

        //glitch fix. If the line is missing then two frequent key presses at then end of line
        // throws an exception  Time range for this glitch - CURSOR_DELAY
        if (!insertMode && caretPosition == text.length()) insertMode = true;

        if (insertMode)
            text.insert(caretPosition, ch);
        else
            text.setCharAt(caretPosition, ch);

        indexText();

        return true;
    }

    /**
     * Returns the text that is presented by this text component.
     */
    public String getText() {
        return text.toString();
    }

    /**
     * Sets the text that is presented by this
     * text component to be the specified text.
     *
     * @param newText the new text.
     */
    public void setText(String newText) {
        if (newText == null) {
            text = new StringBuffer();
        } else {
            text = new StringBuffer(newText);
        }

        //split the text onto substrings
        indexText();

        setCaretPosition(text.length());

    }

    /**
     * Appends the given text to the text area's current text.
     */
    public void appendText(String str) {
        text.append(str);
        //split the text onto substrings
        indexText();

        //apply changes
        setCaretPosition(text.length());
    }

    /**
     * Inserts the specified text at the specified position
     * in this text area.
     */
    public void insertText(String str, int pos) {
        //inserts the text
        text.insert(pos, str);
        //set new position
        caretPosition = pos + str.length();
        //split the text onto substrings
        indexText();
        //apply changes
        setCaretPosition(0, 0);
    }

    public void reset(Font font) {
        this.font = font;
        setText(getText());
    }

    /**
     * Returns the range for the specified offset
     */
    protected int findRange(int pos) {
        int size = linebreaks.size();
        LineRange range;

        //Move by substrings looking for caret position
        for (int i = 0; i < size; i++) {
            range = (LineRange) linebreaks.elementAt(i);
            //if caret belongs to this substring
            if (pos >= range.from && pos <= range.to)
                return i;
        }

        return -1; //not found
    }

    public int getCaretPosition() {
        return caretPosition;
    }

    /**
     *  Sets cater position to specified position
     */
    public boolean setCaretPosition(int pos) {
        int n;

        caretPosition = pos;
        startRow = 0;
        caretPositionY = 0;
        caretPositionX = 0;
        currentRange = new LineRange(0, 0);

        //get substring number
        n = findRange(pos);
        if (n == -1) return false;

        //set the currect substring
        currentRange = (LineRange) linebreaks.elementAt(n);
        //set starting string and cursor position
        while (startRow + caretPositionY != n) {
            caretPositionY++;

            if (caretPositionY >= nRows) {
                startRow++;
                caretPositionY--;
            }

        }
        caretPositionX = pos - currentRange.from;

        return true;
    }

    /**
     * Default destructor. Helps VM to perform garbage collection
     */
    public void destructor() {
        linebreaks = null;
        text = null;
        currentRange = null;
    }

    public int getCurrentLength() {
//        return text.length();
        return 0;
    }

    public char[] getChars() {
//        return getText().toCharArray();
        return null;
    }

} // class TextAreaText

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -