//作業コードの 2 番目の部分
/** Creates a new terminal. */
public Terminal()
{
line_ = new TerminalLine[HEIGHT];
for(int y = 0; y < HEIGHT; ++y) {
line_[y] = new TerminalLine(WIDTH);
}
setBackground(DARK_GREY);
setForeground(LIGHT_GREY);
setFont( new Font("Monospaced", Font.PLAIN, 12) );
clearScreen();
}
public static void captureLines(){
String line;
try{
heightCounter=Terminal.HEIGHT;
BufferedReader tempIn = new BufferedReader(new FileReader("temp"));
term.println("");
lines = new ArrayList();
while((line = tempIn.readLine())!=null)
{
lines.add(line);
}
tempIn.close();
}catch(Exception e){System.out.println(e);}
return;
}
public static void printPage(int index){
try{
if(index<lines.size()){
for (int i=0; i<25; i++){
if(index==lines.size())
return;
//System.out.println(index+" "+lines.get(index));
term.println(lines.get(index).toString());
index++;
}Thread.sleep(500);
printPage(index);
}else{return;}
}catch(Exception e){System.out.println(e);}
}
public static String getCurrentLine(){
TerminalLine currentLine = line_[getYCursor()];
String command="";
for(char c: currentLine.data){
command+= c;
}
String outString = command.substring(2);
return (outString.trim());
}
public synchronized void clearScreen()
{
for(int y = 0; y < HEIGHT; ++y) {
clearLine(y);
}
repaint();
}
public synchronized void clearLine(int line)
{
clearLine(line, 0, WIDTH-1);
}
public synchronized void clearLine(int y, int x0, int x1)
{
Color bg = getBackground();
Color fg = getForeground();
TerminalLine line = line_[y];
for(int x = x0; x <= x1; ++x) {
line.data[x] = ' ';
line.bgColor[x] = bg;
line.fgColor[x] = fg;
line.effects[x] = 0;
}
}
public synchronized boolean getCursorVisible()
{ return cursorVisible_; }
public synchronized char getData(int x, int y)
{
return line_[y].data[x];
}
public synchronized Color getBgColor(int x, int y)
{
return line_[y].bgColor[x];
}
public synchronized byte getEffects(int x, int y)
{
return line_[y].effects[x];
}
public synchronized Color getFgColor(int x, int y)
{
return line_[y].fgColor[x];
}
public synchronized Dimension getMaximumSize()
{
return getPreferredSize();
}
public synchronized Dimension getMinimumSize()
{
return getPreferredSize();
}
public synchronized Dimension getPreferredSize()
{
return new Dimension(WIDTH * tileWidth_, HEIGHT * tileHeight_);
}
public boolean getReverseVideo()
{ return reverseVideo_; }
public synchronized boolean getScroll()
{ return scroll_; }
public synchronized int getTab()
{ return tab_; }
public int getTileWidth()
{ return tileWidth_; }
public int getTileHeight()
{ return tileHeight_; }
public synchronized int getXOffset()
{ return xOffset_; }
public synchronized int getYOffset()
{ return yOffset_; }
public synchronized int getXCursor()
{ return xCursor_; }
public static synchronized int getYCursor()
{ return yCursor_; }
public synchronized void gotoxy(int x, int y)
{
xCursor_ = x;
yCursor_ = y;
}
public synchronized void print(String s)
{
print(null, null, s);
}
public synchronized void print(Color bg, Color fg, String s)
{
for(int i = 0, len = s.length(); i < len; ++i) {
print(bg, fg, s.charAt(i) );
}
repaint();
}
public synchronized void print(char c)
{
print(null, null, c);
}
public synchronized void print(Color bg, Color fg, char c)
{
if( escapeMode_ == ESC_NORMAL ) {
switch(c) {
case 7: // 7 = BEL, bell
bell();
break;
case '\b': // 8 = BS, backspace
--xCursor_;
break;
case '\t': // 9 = HT, tab
xCursor_ = ((xCursor_ + tab_) / tab_) * tab_;
break;
case '\n': // 10 = LF, newline
xCursor_ = 0;
++yCursor_;
//flag set to allow printing of ">>" prompt
isNew=true;
break;
case 11: // 11 = VT, vertical tab
case '\f': // 12 = FF, form feed
++yCursor_;
break;
case '\r': // 13 = CR, ignored because Java's newline is \n
break;
case 27: // 27 = ESC, enters escape mode
escapeMode_ = ESC_ESCAPE;
break;
case 127: { // 127 = DEL, right-delete
int yc = yCursor_;
TerminalLine line = line_[yc];
for(int x = xCursor_; x < WIDTH-1; ++x) {
line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
line.data[x+1], line.effects[x+1] );
}
setData(WIDTH-1, yc, null, null, ' ');
break;
}
default:
if( c < 32 ) {
// unknown control character
bell();
} else {
setData(xCursor_, yCursor_, bg, fg, c);
++xCursor_;
}
}
} else {
escapeMode_ = doEscape(c);
}
// wrap cursor
if( xCursor_ < 0 ) {
if( wrap_ ) {
xCursor_ = WIDTH-1;
--yCursor_;
} else {
xCursor_ = 0;
}
} else if( xCursor_ >= WIDTH ) {
if( wrap_ ) {
xCursor_ = 0;
++yCursor_;
} else {
xCursor_ = WIDTH-1;
}
}
if( yCursor_ < 0 ) {
if( scroll_ ) {
scrollDown(0);
}
yCursor_ = 0;
} else if( yCursor_ >= HEIGHT ) {
if( scroll_ ) {
scrollUp(0);
}
yCursor_ = HEIGHT-1;
}
//cool flags here to print ">>" prompt: 1. when there is new line and 2. when the isR flag has detected the end of printing in the return event.
if(isR){
isNew=false;
}
if(isNew){
isNew=false;
print(DARK_GREY, YELLOW, ">>");
}
}
public synchronized void scrollDown(int topline)
{
// scroll down, exposing a blank line at top
// don't waste the existing array, recycle it.
TerminalLine line0 = line_[HEIGHT-1];
// move all lines down
for(int y = HEIGHT-1; y > topline; --y) {
line_[y] = line_[y-1];
}
// put it at the top
line_[topline] = line0;
clearLine(topline);
}
public synchronized void scrollUp(int topline)
{
// scroll up, exposing a blank line at bottom
// don't waste the existing array, recycle it.
TerminalLine line0 = line_[topline];
// move all lines up
for(int y = topline; y < HEIGHT-1; ++y) {
line_[y] = line_[y+1];
}
// put it at the end
line_[HEIGHT-1] = line0;
clearLine(HEIGHT-1);
}
private int doEscape(char c)
{
switch(escapeMode_) {
case ESC_NORMAL:
throw new IllegalStateException();
case ESC_ESCAPE:
// handled below
break;
case ESC_POS_Y:
escapeHold_ = Math.max(0, Math.min(HEIGHT-1, (int)(c - 32)));
return ESC_POS_X;
case ESC_POS_X:
yCursor_ = escapeHold_;
xCursor_ = Math.max(0, Math.min(WIDTH-1, (int)(c - 32)));
return ESC_NORMAL;
case ESC_FGCOLOR:
setForeground( getColor( (int)c ) );
return ESC_NORMAL;
case ESC_BGCOLOR:
setBackground( getColor( (int)c ) );
return ESC_NORMAL;
default:
throw new IllegalStateException("Unknown escape mode "+escapeMode_);
}
switch(c) {
case 24: // 24 = CAN, cancel escape
case 26: // 26 = SUB, cancel escape
case 27: // 27 = ESC, cancel escape
return ESC_NORMAL;
case 'A': // Cursor Up
if( yCursor_ > 0 ) {
--yCursor_;
}
return ESC_NORMAL;
case 'B': // Cursor Down
if( yCursor_ < HEIGHT-1 ) {
++yCursor_;
}
return ESC_NORMAL;
case 'C': // Cursor Forward
if( xCursor_ < WIDTH-1 ) {
++xCursor_;
}
return ESC_NORMAL;
case 'D': // Cursor Backward
if( xCursor_ > 0 ) {
--xCursor_;
}
return ESC_NORMAL;
case 'E': // Clear Screen, Home Cursor
clearScreen();
xCursor_ = 0;
yCursor_ = 0;
return ESC_NORMAL;
case 'H': // Home Cursor
xCursor_ = 0;
yCursor_ = 0;
return ESC_NORMAL;
case 'I': // Reverse Index
--yCursor_;
return ESC_NORMAL;
case 'J': // Erase to End of Page
clearLine(yCursor_, xCursor_, WIDTH-1);
for(int y = yCursor_+1; y < HEIGHT; ++y) {
clearLine(y);
}
return ESC_NORMAL;
case 'K': // Erase to End of Line
clearLine(yCursor_, xCursor_, WIDTH-1);
return ESC_NORMAL;
case 'L': // Insert Line
scrollDown(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'M': // Delete Line
scrollUp(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'N': { // Delete Character
int yc = yCursor_;
TerminalLine line = line_[yc];
for(int x = xCursor_; x < WIDTH-1; ++x) {
line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
line.data[x+1], line.effects[x+1] );
}
setData(WIDTH-1, yc, null, null, ' ');
break;
}
case 'Y': // Position Cursor
return ESC_POS_Y;
case 'b': // Set Foreground Color
return ESC_FGCOLOR;
case 'c': // Set Background Color
return ESC_BGCOLOR;
case 'd': { // Erase from Beginning of Display
int xc = xCursor_, yc = yCursor_;
clearLine(yc, 0, xc);
for(int y = 0; y < yc; ++y) {
clearLine(y);
}
return ESC_NORMAL;
}
case 'j': // Save Cursor Position
xCursorSave_ = xCursor_;
yCursorSave_ = yCursor_;
return ESC_NORMAL;
case 'k': // Restore Cursor Position
xCursor_ = xCursorSave_;
yCursor_ = yCursorSave_;
return ESC_NORMAL;
case 'l': // Erase Entire Line
clearLine(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'm': // Enable Cursor
cursorVisible_ = true;
return ESC_NORMAL;
case 'n': // Disable Cursor
cursorVisible_ = false;
return ESC_NORMAL;
case 'o': // Erase from Beginning of Line
clearLine(yCursor_, 0, xCursor_);
return ESC_NORMAL;
case 'p': // Enable Reverse Video
reverseVideo_ = true;
return ESC_NORMAL;
case 'q': // Disable Reverse Video
reverseVideo_ = false;
return ESC_NORMAL;
case 'r': // Enable Underlining
effects_ |= EFFECTS_UNDERLINE;
return ESC_NORMAL;
case 'u': // Disable Underlining
effects_ &= ~EFFECTS_UNDERLINE;
return ESC_NORMAL;
case 'v': // Enable Wrapping
wrap_ = true;
return ESC_NORMAL;
case 'w': // Disable Wrapping
wrap_ = false;
return ESC_NORMAL;
}
// unknown escape code
bell();
return ESC_NORMAL;
}
public synchronized void println(String s)
{
println(null, null, s);
}
public synchronized void println(Color bg, Color fg, String s)
{
print(bg, fg, s);
print(bg, fg, '\n');
repaint();
}
public synchronized void setCursorVisible(boolean c)
{ cursorVisible_ = c; }
public synchronized void setData(int x, int y, char c)
{
setData(x, y, null, null, c);
}
public synchronized void setData(int x, int y, Color bg, Color fg, char c)
{
setData(x, y, bg, fg, c, effects_);
}
public synchronized void setData(int x, int y, Color bg, Color fg, char c, byte effects)
{
if( bg == null ) {
bg = getBackground();
}
if( fg == null ) {
fg = getForeground();
}
if( reverseVideo_ ) {
Color tmp = bg;
bg = fg;
fg = tmp;
}
TerminalLine line = line_[y];
line.data[x] = c;
line.bgColor[x] = bg;
line.fgColor[x] = fg;
line.effects[x] = effects;
}
public synchronized void setBgColor(int x, int y, Color b)
{
line_[y].bgColor[x] = b;
}
public synchronized void setEffects(int x, int y, byte e)
{
line_[y].effects[x] = e;
}
public synchronized void setFgColor(int x, int y, Color f)
{
line_[y].fgColor[x] = f;
}
public void setFont(Font font)
{
super.setFont(font);
FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
tileWidth_ = fm.charWidth('W');
tileHeight_ = fm.getHeight() - fm.getDescent();
xOffset_ = 0;
yOffset_ = -fm.getDescent();
//System.out.println("tile "+tileWidth_+"x"+tileHeight_+", offset="+xOffset_+","+yOffset_);
}
public void setReverseVideo(boolean r)
{ reverseVideo_ = r; }
public synchronized void setScroll(boolean s)
{ scroll_ = s; }
public synchronized void setTab(int t)
{ tab_ = t; }
public void setTileSize(int w, int h)
{
tileWidth_ = w;
tileHeight_ = h;
buffer_ = null;
}
public synchronized void setXOffset(int x)
{ xOffset_ = x; }
public synchronized void setYOffset(int y)
{ yOffset_ = y; }
public synchronized void setXCursor(int x)
{ xCursor_ = x; }
public synchronized void setYCursor(int y)
{ yCursor_ = y; }
public synchronized void paint(Graphics g)
{
if( buffer_ != null ) {
g.drawImage(buffer_, 0, 0, null);
}
}
public synchronized void update(Graphics gg)
{
if( buffer_ == null ) {
Dimension d = getPreferredSize();
buffer_ = createImage(d.width, d.height);
if( buffer_ == null ) {
repaint(100L); //wtf?
return;
}
}
Graphics g = buffer_.getGraphics();
g.setFont( getFont() );
FontMetrics fm = g.getFontMetrics();
char[] cbuf = new char[1]; // for drawChars
for(int y = 0; y < HEIGHT; ++y) {
int sy = y * tileHeight_;
TerminalLine line = line_[y];
for(int x = 0; x < WIDTH; ++x) {
int sx = x * tileWidth_;
// background
g.setColor( line.bgColor[x] );
g.fillRect(sx, sy, tileWidth_, tileHeight_);
// character
g.setColor( line.fgColor[x] );
cbuf[0] = line.data[x];
g.drawChars(cbuf, 0, 1, sx + xOffset_,
sy + fm.getAscent() + yOffset_);
// effects
if( (line.effects[x] & EFFECTS_UNDERLINE) != 0 ) {
g.drawLine(sx, sy+tileHeight_-1,
sx+tileWidth_-1, sy+tileHeight_-1);
}
// borders for testing
//g.drawLine(sx, sy, sx+tileWidth_-1, sy);
//g.drawLine(sx, sy, sx, sy+tileHeight_-1);
}
}
if( cursorVisible_ ) {
Color bg = getBgColor(xCursor_, yCursor_);
if( bg == BLACK ) {
bg = WHITE;
}
g.setXORMode(bg);
g.fillRect(xCursor_ * tileWidth_, yCursor_ * tileHeight_,
tileWidth_, tileHeight_);
g.setPaintMode();
}
paint(gg);
}
}
class TerminalLine
{
public Color[] bgColor;
public Color[] fgColor;
public char[] data;
public byte[] effects;
public TerminalLine(int width)
{
bgColor = new Color[width];
fgColor = new Color[width];
data = new char[width];
effects = new byte[width];
}
public void setData(int x, Color bg, Color fg, char c, byte e)
{
data[x] = c;
bgColor[x] = bg;
fgColor[x] = fg;
effects[x] = e;
}
}