我现在有个项目,它都已经写的差不多了,但我看不懂,我不知道是用什么思想去模拟终端的,大概意思是用一个byte的二维数组,每个字符占一格,具体怎么看待的,我就不知道了,哎理解别人的代码真累。 以下是这个类的代码 public class VT100 extends JComponent { private static final long serialVersionUID = -5704767444883397941L; private Application parent;
// 畫面的寬與高 private int width, height;
// 模擬螢幕的相關資訊 private int maxrow, maxcol; // terminal 的大小 private int toprow; // 第一 row 所在位置 private int scrolluprow; // 往上捲的行數 private int scrolllines; // scroll buffer 的行數 private int totalrow, totalcol; // 總 row, col 數,包含 scroll buffer private int topmargin, buttommargin, leftmargin, rightmargin;
// 螢幕 translate 的座標 private int transx, transy;
// 字元的垂直與水平間距 private int fontverticalgap, fonthorizontalgap, fontdescentadj;
// 各種字型參數 private Font font; private int fontwidth, fontheight, fontdescent; private int fontsize;
text = new char[totalrow][totalcol]; mbc = new int[totalrow][totalcol]; fgcolors = new byte[totalrow][totalcol]; bgcolors = new byte[totalrow][totalcol]; attributes = new byte[totalrow][totalcol]; selected = new boolean[totalrow][totalcol]; isurl = new boolean[totalrow][totalcol];
textBuf = new byte[4]; attrBuf = new byte[4]; fgBuf = new byte[4]; bgBuf = new byte[4]; textBufPos = 0;
如果模拟终端通过协议和服务通讯的话,还需要解析协议内容,不过这个和模拟终端无关。
以下是这个类的代码
public class VT100 extends JComponent
{
private static final long serialVersionUID = -5704767444883397941L; private Application parent;
// 畫面的寬與高
private int width, height;
// 模擬螢幕的相關資訊
private int maxrow, maxcol; // terminal 的大小
private int toprow; // 第一 row 所在位置
private int scrolluprow; // 往上捲的行數
private int scrolllines; // scroll buffer 的行數
private int totalrow, totalcol; // 總 row, col 數,包含 scroll buffer
private int topmargin, buttommargin, leftmargin, rightmargin;
// 螢幕 translate 的座標
private int transx, transy;
// 字元的垂直與水平間距
private int fontverticalgap, fonthorizontalgap, fontdescentadj;
// 各種字型參數
private Font font;
private int fontwidth, fontheight, fontdescent;
private int fontsize;
// 處理來自使用者的事件
private User user;
// 畫面
private BufferedImage bi;
// 各種參數
private Config resource;
// 轉碼用
private Convertor conv;
private String encoding;
private String emulation;
// 目前、上次、儲存的游標所在位址
private int ccol, crow;
private int lcol, lrow;
private int scol, srow;
// 儲存螢幕上的相關資訊
private char[][] text; // 轉碼後的 char
private int[][] mbc; // multibyte character 的第幾個 byte
private byte[][] attributes; // 屬性
private byte[][] fgcolors; // 前景色
private byte[][] bgcolors; // 背景色
private boolean[][] selected; // 是否被滑鼠選取
// 目前的屬性及前景、背景色
private byte cattribute;
private byte cfgcolor, cbgcolor;
// 記錄螢幕上何處需要 repaint
private FIFOSet repaintSet;
private Object repaintLock;
// 判斷畫面上的網址
private boolean[][] isurl;
private int urlstate;
private Vector probablyurl;
private boolean addurl;
// 把從 nvt 來的資料暫存起來
private byte[] nvtBuf;
private int nvtBufPos, nvtBufLen;
// multibytes char 暫存
private byte[] textBuf;
private byte[] attrBuf, fgBuf, bgBuf;
private int textBufPos;
// 記錄游標是否位於最後一個字上,非最後一個字的下一個
private boolean linefull;
// 預設顏色設定,前景、背景、游標色
private static byte defFg = 7;
private static byte defBg = 0;
private static byte defAttr = 0;
// 各種屬性
private static final byte BOLD = 1;
private static final byte UNDERLINE = 8;
private static final byte BLINK = 16;
private static final byte REVERSE = 64;
// 取得色彩用的一些狀態
private static final byte FOREGROUND = 0;
private static final byte BACKGROUND = 1;
private static final byte CURSOR = 2;
private static final byte URL = 3;
// ASCII
// private static final byte BEL = 7;
// private static final byte BS = 8;
// private static final byte TAB = 9;
// private static final byte LF = 10;
// private static final byte VT = 11;
// private static final byte FF = 12;
// private static final byte CR = 13;
// private static final byte SO = 14;
// private static final byte SI = 15;
// 閃爍用
private int text_blink_count, cursor_blink_count;
private boolean text_blink, cursor_blink;
// 調色盤
private static Color[] normal_colors = {
new Color( 0, 0, 0),
new Color( 128, 0, 0 ),
new Color( 0, 128, 0 ),
new Color( 128, 128, 0),
new Color( 0, 0, 128 ),
new Color( 128, 0, 128 ),
new Color( 0, 128, 128 ),
new Color( 192, 192, 192 ),
};
private static Color[] highlight_colors = {
new Color( 128, 128, 128),
new Color( 255, 0, 0 ),
new Color( 0, 255, 0 ),
new Color( 255, 255, 0),
new Color( 0, 0, 255 ),
new Color( 255, 0, 255 ),
new Color( 0, 255, 255 ),
new Color( 255, 255, 255 ),
};
private static Color cursorColor = Color.GREEN;
private static Color urlColor = Color.ORANGE;
public static final int NUMERIC_KEYPAD = 1;
public static final int APPLICATION_KEYPAD = 2;
private int keypadmode;
// 重繪用的 Timer
private Timer ti;
// 紀錄是否所有初始化動作皆已完成
private boolean init_ready;
private void initValue()
{
// 讀入模擬終端機的大小,一般而言是 80 x 24
maxcol = resource.getIntValue( Config.TERMINAL_COLUMNS );
maxrow = resource.getIntValue( Config.TERMINAL_ROWS );
// 讀入 scroll buffer 行數
scrolllines = resource.getIntValue( Config.TERMINAL_SCROLLS );
// 所需要的陣列大小
totalrow = maxrow + scrolllines;
totalcol = maxcol;
// 一開始環狀佇列的起始點在 0
toprow = 0;
// 預設 margin 為整個螢幕
topmargin = 1;
buttommargin = maxrow;
leftmargin = 1;
rightmargin = maxcol;
// 游標起始位址在螢幕左上角處
ccol = crow = 1;
lcol = lrow = 1;
scol = srow = 1;
// 設定目前色彩為預設值
cfgcolor = defFg;
cbgcolor = defBg;
cattribute = defAttr;
urlstate = 0;
addurl = false;
probablyurl = new Vector();
text_blink_count = 0;
cursor_blink_count = 0;
text_blink = true;
cursor_blink = true;
linefull = false;
keypadmode = NUMERIC_KEYPAD;
}
{
int i, j;
// 從上層讀取資料用的 buffer
nvtBuf = new byte[4096];
nvtBufPos = nvtBufLen = 0;
text = new char[totalrow][totalcol];
mbc = new int[totalrow][totalcol];
fgcolors = new byte[totalrow][totalcol];
bgcolors = new byte[totalrow][totalcol];
attributes = new byte[totalrow][totalcol];
selected = new boolean[totalrow][totalcol];
isurl = new boolean[totalrow][totalcol];
textBuf = new byte[4];
attrBuf = new byte[4];
fgBuf = new byte[4];
bgBuf = new byte[4];
textBufPos = 0;
// 初始化記載重繪位置用 FIFOSet
// XXX: 假設 column 數小於 256
repaintSet = new FIFOSet( totalrow << 8 );
repaintLock = new Object();
for( i = 0; i < totalrow; i++) {
for( j = 0; j < totalcol; j++) {
text[i][j] = ((char)0);
mbc[i][j] = 0;
fgcolors[i][j] = defFg;
bgcolors[i][j] = defBg;
attributes[i][j] = defAttr;
isurl[i][j] = false;
}
}
for( i = 1; i < maxrow; i++) {
for( j = 1; j < maxcol; j++ )
setRepaint( i, j );
}
}
private void initOthers()
{
// 進入 run() 以後才確定初始化完成
init_ready = false;
// 啟動閃爍控制 thread
ti = new Timer( 250, new RepaintTask() );
ti.start();
// 取消 focus traversal key, 這樣才能收到 tab.
setFocusTraversalKeysEnabled( false );
// Input Method Framework, set passive-client
enableInputMethods( true );
// 設定預設大小
// FIXME: magic number
setSize( new Dimension( 800, 600 ) );
// User
user = new User( parent, this, resource );
addKeyListener( user );
addMouseListener( user );
addMouseMotionListener( user );
}
{
// 讀入模擬終端機的大小,一般而言是 80 x 24
maxcol = resource.getIntValue( Config.TERMINAL_COLUMNS );
maxrow = resource.getIntValue( Config.TERMINAL_ROWS );
// 讀入 scroll buffer 行數
scrolllines = resource.getIntValue( Config.TERMINAL_SCROLLS );
// 所需要的陣列大小
totalrow = maxrow + scrolllines;
totalcol = maxcol;
// 一開始環狀佇列的起始點在 0
toprow = 0;
// 預設 margin 為整個螢幕
topmargin = 1;
buttommargin = maxrow;
leftmargin = 1;
rightmargin = maxcol;
// 游標起始位址在螢幕左上角處
ccol = crow = 1;
lcol = lrow = 1;
scol = srow = 1;
// 設定目前色彩為預設值
cfgcolor = defFg;
cbgcolor = defBg;
cattribute = defAttr;
urlstate = 0;
addurl = false;
probablyurl = new Vector();
text_blink_count = 0;
cursor_blink_count = 0;
text_blink = true;
cursor_blink = true;
linefull = false;
keypadmode = NUMERIC_KEYPAD;
}
// 儲存螢幕上的相關資訊
private char[][] text; // 轉碼後的 char
private int[][] mbc; // multibyte character 的第幾個 byte
private byte[][] attributes; // 屬性
private byte[][] fgcolors; // 前景色
private byte[][] bgcolors; // 背景色
private boolean[][] selected; // 是否被滑鼠選取 和
text = new char[totalrow][totalcol];
mbc = new int[totalrow][totalcol];
fgcolors = new byte[totalrow][totalcol];
bgcolors = new byte[totalrow][totalcol];
attributes = new byte[totalrow][totalcol];
selected = new boolean[totalrow][totalcol];
isurl = new boolean[totalrow][totalcol]; 上来看,这个实现是利用二维数组来记录屏幕上每个点的文本和属性。很好理解啊。甚至鼠标的选取都用数据保存。