textarea.java.svn-base

来自「j2me设计的界面包」· SVN-BASE 代码 · 共 804 行 · 第 1/2 页

SVN-BASE
804
字号
    /**
     * @inheritDoc
     */
    public boolean isScrollableY() {
        return (rowsGap + getStyle().getFont().getHeight()) * getLines() > getHeight();
    }

    /**
     * @inheritDoc
     */
    protected void paintScrollbarY(Graphics g) {
        int prefH = (rowsGap + getStyle().getFont().getHeight()) * getLines();
        float offset = ((float) getScrollY()) / ((float) prefH);
        float block = ((float) getHeight()) / ((float) prefH);
        UIManager.getInstance().getLookAndFeel().drawVerticalScroll(g, this, offset, block);
    }
    
    void onClick(){
        if(isEditable()) {
            editString();
        }
    }
        
    void editString() {
        if(autoDegradeMaxSize && (!hadSuccessfulEdit) && (maxSize > 1024)) {
            try {
                Display.getInstance().editString(this, getMaxSize(), getConstraint(), getText());
            } catch(IllegalArgumentException err) {
                maxSize -= 1024;
                setDefaultMaxSize(maxSize);
                editString();
            }
        } else {
            Display.getInstance().editString(this, getMaxSize(), getConstraint(), getText());
        }
    }
    
    /**
     * @inheritDoc
     */
    public void pointerReleased(int x, int y) {
        super.pointerReleased(x, y);
        if(isEditable()){
            onClick();
        }
    }

    /**
     * @inheritDoc
     */
    void focusGainedInternal() {
        super.focusGainedInternal();
        setHandlesInput(isScrollableY());
    }

    /**
     * @inheritDoc
     */
    void focusLostInternal() {
        super.focusLostInternal();
        setHandlesInput(false);
    }
    
    /**
     * Returns the number of columns in the text area
     * 
     * @return the number of columns in the text area
     */
    public int getColumns() {
        return columns;
    }
    
    /**
     * Returns the number of rows in the text area
     * 
     * @return the number of rows in the text area
     */
    public int getRows() {
        return rows;
    }
    
    /**
     * Sets the number of columns in the text area
     * 
     * @param columns number of columns
     */
    public void setColumns(int columns) {
        setShouldCalcPreferredSize(true);
        this.columns = columns;
    }
    
    /**
     * Sets the number of rows in the text area
     * 
     * @param rows number of rows
     */
    public void setRows(int rows) {
        setShouldCalcPreferredSize(true);
        this.rows = rows;
    }
    
    /**
     * @inheritDoc
     */
    protected String getUIID() {
        return id;
    }

    void initComponentImpl() {
        super.initComponentImpl();
        getRowStrings();
    }
    
    private Vector getRowStrings() {
        if(rowStrings == null || widthForRowCalculations != getWidth()){
            initRowString();
            setShouldCalcPreferredSize(true);
            //setPreferredH(getStyle().getPadding(TOP) + getStyle().getPadding(BOTTOM) + (getStyle().getFont().getHeight() + rowsGap)*rowStrings.size());
        }
        return rowStrings;
    }
    
    
    /**
     * Returns the number of text lines in the TextArea
     * 
     * @return the number of text lines in the TextArea
     */
    public int getLines(){
        int retVal;
        Vector v = getRowStrings();
        v.trimToSize();
        retVal = v.size();
        if(growByContent){
            rows = Math.max(rows, retVal);
        }
        return retVal;
    }
    
    /**
     * Returns the text in the given row of the text box
     * 
     * @param line the line number in the text box
     */
    public String getTextAt(int line){
        Vector rowsV = getRowStrings();
        return (String)rowsV.elementAt(line);
    }
    
    private int indexOf(char[] t, char c, int offset) {
        for(int iter = offset ; iter < t.length ; iter++) {
            if(t[iter] == c) {
                return iter;
            }
        }
        return -1;
    }
    
    private boolean fastCharWidthCheck(char[] chrs, int off, int length, int width, int charWidth, Font f) {
        if(length * charWidth < width) {
            return true;
        }
        return f.charsWidth(chrs, off, length) < width;
    }
    
    private void initRowString() {
        rowStrings= new Vector();
        widthForRowCalculations = getWidth();
        
        // single line text area is essentially a text field
        if(rows == 1) {
            rowStrings.addElement(getText());
            return;
        }
        if(text == null || text.equals("")){
            return;
        }
        char[] text = getText().toCharArray();
        
        Style style = getStyle();
        Font font = style.getFont();
        int charWidth = font.charWidth('W');
        int textAreaWidth = getWidth()- style.getPadding(RIGHT) - style.getPadding(LEFT)- 
            style.getMargin(RIGHT) - style.getMargin(LEFT); //(border(=gap) + gap )*2
        if(textAreaWidth <= 0) {
            textAreaWidth = Math.min(10, columns) * charWidth;
        }
        int minCharactersInRow = Math.max(1, textAreaWidth / charWidth);
        int rowIndex=0;
        int from=0;
        int to=from+minCharactersInRow;
        int textLength=text.length;
        String rowText;
        int i,spaceIndex;
        // if there is any possibility of a scrollbar we need to reduce the textArea
        // width to accomodate it
        if(textLength / minCharactersInRow > Math.max(2, rows)) {
            textAreaWidth -= UIManager.getInstance().getLookAndFeel().getVerticalScrollWidth();
        }
        
        /*
        iteration over the string using indexes, from - the begining of the row , to - end of a row
        for each row we will try to search for a "space" character at the end of the row ( row is text area available width)
        indorder to improve the efficiency we do not search an entire row but we start from minCharactersInRow which indicates
        what is the minimum amount of characters that can feet in the text area width.
        if we dont find we will go backwards and search for the first space available,
        if there is no space in the entire row we will cut the line inorder to fit in.
         */
        if(textLength<=minCharactersInRow){
            rowStrings.addElement(new String(text));
        } else{
            while(to<textLength) {
                if(to>textLength){
                    to=textLength;
                }
                
                spaceIndex=-1;
                rowText="";
                int maxLength = to;
                
                // search for "space" character at close as possible to the end of the row
                for( i=to; i < textLength && fastCharWidthCheck(text, from, i - from, textAreaWidth, charWidth, font)  ; i++){
                    char c = text[i];
                    if(c == ' ' || c == '\n' || c == '\t') {
                        spaceIndex=i;
                    }
                    maxLength++;
                }
                
                // if we got to the end of the text use the entire row,
                // also if space is next character (in the next row) we can cut the line
                if(i == textLength || text[i] == ' ' || text[i] == '\n') {
                    spaceIndex=i;
                }
                
                // if we found space in the limit width of the row (searched only from minCharactersInRow)
                if(spaceIndex!=-1){
                    // make sure that if we have a newline character before the end of the line we should
                    // break there instead
                    int newLine = indexOf(text, '\n', from + 1);
                    if(newLine > -1 && newLine < spaceIndex) {
                        spaceIndex = newLine;
                    }
                    
                    rowText = new String(text, from, spaceIndex - from);
                    from=spaceIndex+1;
                    
                } // if there is no space from minCharactersInRow to limit need to search backwards
                else{
                    for( i=to; spaceIndex==-1 && i>=from ; i--){
                        char chr = text[i];
                        if(chr == ' ' || chr == '\n' || chr == '\t') {
                            spaceIndex=i;
                            rowText = new String(text, from, spaceIndex - from);
                            from=spaceIndex+1;
                        }
                        
                    }
                    if(spaceIndex==-1) {
                        // from = to + 1;
                        spaceIndex = maxLength;
                        rowText = new String(text, from, spaceIndex - from);
                        from = spaceIndex;
                    }
                }
                
                rowStrings.addElement(rowText); 
                //adding minCharactersInRow doesn't work if what is left is less
                //then minCharactersInRow
                to=from;//+minCharactersInRow;
                rowIndex++;
                
            }
        }
    }
    
    /**
     * Gets the num of pixels gap between the rows
     * 
     * @return the gap between rows in pixels
     */
    public int getRowsGap() {
        return rowsGap;
    }

    /**
     * The gap in pixels between rows
     * 
     * @param rowsGap num of pixels to gap between rows
     */
    public void setRowsGap(int rowsGap) {
        this.rowsGap = rowsGap;
    }
    
    /**
     * @inheritDoc
     */
    public void paint(Graphics g) {
        UIManager.getInstance().getLookAndFeel().drawTextArea(g, this);
    }
    
    /**
     * @inheritDoc
     */
    protected Dimension calcPreferredSize(){
        return UIManager.getInstance().getLookAndFeel().getTextAreaPreferredSize(this);
    }
        
    /**
     * Add an action listener which is invoked when the text area was modified not during
     * modification. A text <b>field</b> might never fire an action event if it is edited
     * in place and the user never leaves the text field!
     * 
     * @param a actionListener
     */
    public void addActionListener(ActionListener a) {
        if(actionListeners == null) {
            actionListeners = new Vector();
        }
        if(!actionListeners.contains(a)) {
            actionListeners.addElement(a);
        }
    }

    /**
     * Removes an action listener
     * 
     * @param a actionListener
     */
    public void removeActionListener(ActionListener a) {
        if(actionListeners == null) {
            actionListeners = new Vector();
        }
        actionListeners.removeElement(a);
    }
    
    /**
     * Notifies listeners of a change to the text area
     */
    void fireActionEvent() {
        if(actionListeners != null) {
            ActionEvent evt = new ActionEvent(this);
            for(int iter = 0 ; iter < actionListeners.size() ; iter++) {
                ActionListener a = (ActionListener)actionListeners.elementAt(iter);
                a.actionPerformed(evt);
            }
        }
    }
    
    /**
     * @inheritDoc
     */
    void onEditComplete(String text) {
        setText(text);
    }
    
    /**
     * Sets the default limit for the native text box size
     * 
     * @param value default value for the size of the native text box
     */
    public static void setDefaultMaxSize(int value) {
        defaultMaxSize = value;
    }

    /**
     * Indicates that the text area should "grow" in height based on the content beyond the
     * limits indicate by the rows variable
     * 
     * @return true if the text component should grow and false otherwise
     */
    public boolean isGrowByContent() {
        return growByContent;
    }

    /**
     * Indicates that the text area should "grow" in height based on the content beyond the
     * limits indicate by the rows variable
     * 
     * @param growByContent true if the text component should grow and false otherwise
     */
    public void setGrowByContent(boolean growByContent) {
        this.growByContent = growByContent;
    }
    
    /**
     * Indicates whether a high value for default maxSize will be reduced to a lower
     * value if the underlying platform throws an exception.
     */
    public static void setAutoDegradeMaxSize(boolean value) {
        autoDegradeMaxSize = value;
    }

    /**
     * Indicates whether a high value for default maxSize will be reduced to a lower
     * value if the underlying platform throws an exception.
     */
    public static boolean isAutoDegradeMaxSize() {
        return autoDegradeMaxSize;
    }
}

⌨️ 快捷键说明

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