telnetcanvas.java

来自「j2me学习 简单例子」· Java 代码 · 共 278 行

JAVA
278
字号
/* License *  * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *   *  * Redistribution of source code must retain the above copyright notice, *	this list of conditions and the following disclaimer. *  *  * Redistribution in binary form must reproduce the above copyright notice, *	this list of conditions and the following disclaimer in the *	documentation and/or other materials provided with the distribution. *  * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. *   * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. *   * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility.  */package example.term.telnet;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Font;/*** Canvas that renders the telnet output buffer.*/ public class TelnetCanvas extends Canvas{    private Font font;    private short fontHeight;    private short fontWidth;    private short rows;    private short columns;    private int scrollX;    private int scrollY;    private short insetX;    private short insetY;    private byte[] buffer;    private int cursor;        /**    * Default constructor creates a new telnet canvas.    */    public TelnetCanvas()    {        int width = getWidth();        int height = getHeight();        // get font and metrics        font = Font.getFont(             Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL );         fontHeight = (short) font.getHeight();        fontWidth = (short) font.stringWidth( "w" ); // it's monospaced        // calculate how many rows and columns we can display        columns = (short) ( width / fontWidth );         rows = (short) ( height / fontHeight );        // divide any extra space evenly around edges of screen        insetX = (short) ( ( width - columns*fontWidth ) / 2 );        insetY = (short) ( ( height - rows*fontHeight ) / 2 );        // initialize state        buffer = new byte[rows*columns*4]; // start with 4 screens of buffer        cursor = 0;                // initialize scrollback position        scrollX = 0;        scrollY = 0;    }        /**    * Appends the specified ascii string - no unicode allowed.    */    public void receive( String inString )    {        receive( inString.toCharArray() );    }        /**    * Appends the specified ascii character array - no unicode allowed.    */    public void receive( char[] c )    {        for ( int i = 0; i < c.length; i++ ) receive( (byte) c[i] );     }        /**    * Appends the specified ascii bytes to the output.    */    public void receive( byte[] b )    {        for ( int i = 0; i < b.length; i++ ) receive( b[i] );    }    /**    * Appends the specified ascii byte to the output.    * Backspaces, line feeds, carriage returns, and visible    * characters are supported: all others are ignored.    */    public void receive( byte b )    {        // ignore nulls        if ( b == 0 ) return;         // grow buffer as needed        if ( cursor + columns > buffer.length )        {            try            {                // expand by sixteen screenfuls at a time                byte[] tmp = new byte[ buffer.length + rows*columns*16 ];                System.arraycopy( buffer, 0, tmp, 0, buffer.length );                buffer = tmp;            }             catch ( OutOfMemoryError e )            {                // no more memory to grow: just clear half and reuse the existing buffer                System.err.println( "Could not allocate buffer larger than: " + buffer.length );                int i, half = buffer.length / 2;                for ( i = 0; i < half; i++ ) buffer[i] = buffer[i+half];                for ( i = half; i < buffer.length; i++ ) buffer[i] = 0;                int oldLastScreen = calcLastVisibleScreen();                cursor = cursor - half; // start from last input                if ( scrollY == oldLastScreen ) scrollY = calcLastVisibleScreen();            }       }                // start with the last screen containing the cursor        int offsetY = calcLastVisibleScreen();                switch ( b )        {            case 8: // back space            cursor--;            break;                    case 10: // line feed            cursor = cursor + columns - ( cursor % columns );            break;                        case 13: // carriage return            cursor = cursor - ( cursor % columns );            break;                        default:             if ( b > 31 )             {                 // only show visible characters                buffer[cursor++] = b;            }            // ignore all others        }        // if the user has scrolled back, don't lose        // their position when new input comes in        int newY = calcLastVisibleScreen();        if ( newY != offsetY && offsetY == scrollY )        {            // otherwise, make the latest input visible            scrollY = (short) newY;        }                repaint();    }        public void paint( Graphics g )    {        // clear screen        g.setGrayScale( 0 ); // black        g.fillRect( 0, 0, getWidth(), getHeight() );            // draw content from buffer        g.setGrayScale( 255 ); // white        g.setFont( font );                int i;        byte b;                for ( int y = 0; y < rows; y++ )        {            for ( int x = 0; x < columns; x++ )            {                i = (y+scrollY)*columns+(x+scrollX);                if ( i < buffer.length )                {                    b = buffer[i];                    if ( b != 0 )                    {                        g.drawChar( (char) b,                             insetX + x*fontWidth, insetY + y*fontHeight,                             g.TOP | g.LEFT );                    }                }            }        }    }        public void keyPressed( int keyCode )    {        int gameAction = getGameAction( keyCode );        switch ( gameAction )        {            case DOWN:                // scroll down one row                scrollY++;                if ( scrollY > calcLastVisibleScreen() )                {                    scrollY = calcLastVisibleScreen();                }                repaint();                break;            case UP:                // scroll up one row                scrollY--;                if ( scrollY < 0 ) scrollY = 0;                repaint();                break;            default:                // ignore        }    }        public void keyRepeated( int keyCode )    {        int gameAction = getGameAction( keyCode );        switch ( gameAction )        {            case DOWN:                // scroll down by half a screen                scrollY += rows/2;                if ( scrollY > calcLastVisibleScreen() )                {                    scrollY = calcLastVisibleScreen();                }                repaint();                break;            case UP:                // scroll up by half a screen                scrollY -= rows/2;                if ( scrollY < 0 ) scrollY = 0;                repaint();                break;            default:                // ignore        }    }        /**    * For clarity: calculates the row offset so we don't    * scroll below the most recent visible input.    */    private int calcLastVisibleScreen()    {        return Math.max( 0, (cursor+1) / columns - rows + 1 );    }}

⌨️ 快捷键说明

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