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

📄 flashterminal.java

📁 The Javatm Telnet Application/Applet 很好用的
💻 JAVA
字号:
/* * This file is part of "The Java Telnet Application". * * (c) Matthias L. Jugel, Marcus Mei遪er 1996-2002. All Rights Reserved. * * Please visit http://javatelnet.org/ for updates and contact. * * --LICENSE NOTICE-- * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * --LICENSE NOTICE-- * */package de.mud.flash;import de.mud.terminal.VDUBuffer;import de.mud.terminal.VDUDisplay;import de.mud.terminal.VDUInput;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.Text;import org.jdom.input.SAXBuilder;import org.jdom.output.XMLOutputter;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.StringReader;import java.net.Socket;import java.util.Iterator;public class FlashTerminal implements VDUDisplay, Runnable {  private final static int debug = 0;  private boolean simpleMode = true;  private boolean terminalReady = false;  private VDUBuffer buffer;  private BufferedWriter writer;  private BufferedReader reader;  /** A list of colors used for representation of the display */  private String color[] = {"#000000",                            "#ff0000",                            "#00ff00",                            "#ffff00",                            "#0000ff",                            "#ff00ff",                            "#00ffff",                            "#ffffff",                            null, // bold color                            null, // inverted color  };  public void start(Socket flashSocket) {    try {      if (debug > 0) System.err.println("FlashTerminal: got connection: " + flashSocket);      writer = new BufferedWriter(new OutputStreamWriter(flashSocket.getOutputStream()));      reader = new BufferedReader(new InputStreamReader(flashSocket.getInputStream()));      (new Thread(this)).run();    } catch (IOException e) {      System.err.println("FlashTerminal: unable to accept connection: " + e);    }  }  protected void disconnect() {    // do nothing by default  }  /**   * Output performance information   * @param msg message from the flash client   */  private void perf(String msg) {    System.err.print(System.currentTimeMillis());    System.err.println(" " + msg);  }  public void run() {    char buf[] = new char[1024];    int n = 0;    do {      try {        if (debug > 0)          System.err.println("FlashTerminal: waiting for keyboard input ...");        // read from flash frontend        n = reader.read(buf);        if (n > 0 && buf[0] == '<') {          handleXMLCommand(new String(buf, 0, n - 1));          continue;        }        if (debug > 0)          System.err.println("FlashTerminal: got " + n + " keystokes: " + (n > 0 ? new String(buf, 0, n) : ""));        if (n > 0 && (buffer instanceof VDUInput)) {          if (simpleMode) {            // in simple mode simply write the data to the remote host            // we have to convert the chars to bytes ...            byte tmp[] = new byte[n];            for (int i = 0; i < n - 1; i++) {              tmp[i] = (byte) buf[i];            }            ((VDUInput) buffer).write((byte[]) tmp);          } else {            // write each key for it's own            for (int i = 0; i < n - 1; i++) {              ((VDUInput) buffer).keyTyped((int) buf[i], buf[i], 0);            }          }        }      } catch (IOException e) {        System.err.println("FlashTerminal: i/o exception reading keyboard input");      }    } while (n >= 0);    if (debug > 0) System.err.println("FlashTerminal: end of keyboard input");    disconnect();  }  private SAXBuilder builder = new SAXBuilder();  /**   * Handle XML Commands sent by the remote host.   * @param xml string containing the xml commands   */  private void handleXMLCommand(String xml) {    System.err.println("handleXMLCommand(" + xml + ")");    StringReader src = new StringReader("<root>" + xml.replace('\0', ' ') + "</root>");    try {      Element root = builder.build(src).getRootElement();      Iterator cmds = root.getChildren().iterator();      while (cmds.hasNext()) {        Element command = (Element) cmds.next();        String name = command.getName();        if ("mode".equals(name)) {          simpleMode = "true".equals(command.getAttribute("simple").getValue().toLowerCase());        } else if ("timestamp".equals(name)) {          perf(command.getAttribute("msg").getValue());        } else if ("start".equals(name)) {          terminalReady = true;          buffer.update[0] = true;          redraw();        }      }    } catch (JDOMException e) {      System.err.println("error reading command: " + e);    }  }  // placeholder for the terminal element and the xml outputter  private Element terminal = new Element("terminal");  private XMLOutputter xmlOutputter = new XMLOutputter();  /**   * Redraw terminal (send new/changed terminal lines to flash frontend).   */  public void redraw() {    if (debug > 0)      System.err.println("FlashTerminal: redraw()");    if (terminalReady && writer != null) {      try {        // remove children from terminal        terminal.removeChildren();        if (simpleMode) {          Element result = redrawSimpleTerminal(terminal);          if (result.hasChildren()) {            xmlOutputter.output(result, writer);          }        } else {          xmlOutputter.output(redrawFullTerminal(terminal), writer);        }        writer.write(0);        writer.flush();        if (debug > 0)          System.err.println("FlashTerminal: flushed data ...");      } catch (IOException e) {        System.err.println("FlashTerminal: error writing to client: " + e);        writer = null;      }    }  }  /**   * The simple terminal only draws new lines and ignores   * changes on lines aready written.   * @param terminal   * @return   */  private Element redrawSimpleTerminal(Element terminal) {    terminal.setAttribute("simple", "true");    int checkPoint = buffer.scrollMarker < 0 ? 0 : buffer.scrollMarker;    // first check whether our check point is in the back buffer    while (checkPoint < buffer.screenBase) {      terminal.addContent(redrawLine(0, checkPoint++));    }    // then dive into the screen area ...    while (checkPoint < buffer.bufSize) {      int line = checkPoint - (buffer.screenBase - 1);      if (line > buffer.getCursorRow())        break;      terminal.addContent(redrawLine(0, checkPoint++));    }    // update scroll marker    buffer.scrollMarker = checkPoint;    buffer.update[0] = false;    return terminal;  }  /**   * Redraw a complete terminal with updates on all visible lines.   * @param terminal the root terminal tag to add changed lines to   * @return the final terminal tag   */  private Element redrawFullTerminal(Element terminal) {    // cycle through buffer and create terminal update ...    for (int l = 0; l < buffer.height; l++) {      if (!buffer.update[0] && !buffer.update[l + 1]) continue;      buffer.update[l + 1] = false;      terminal.addContent(redrawLine(l, buffer.windowBase));    }    buffer.update[0] = false;    return terminal;  }  /**   * Redraw a sinle line by looking at chunks and formatting them.   * @param l the current line   * @param base the "window"-base within the buffer   * @return an element with the formatted line   */  private Element redrawLine(int l, int base) {    Element line = new Element("line");    line.setAttribute("row", "" + l);    // determine the maximum of characters we can print in one go    for (int c = 0; c < buffer.width; c++) {      int addr = 0;      int currAttr = buffer.charAttributes[base + l][c];      while ((c + addr < buffer.width) &&              ((buffer.charArray[base + l][c + addr] < ' ') ||              (buffer.charAttributes[base + l][c + addr] == currAttr))) {        if (buffer.charArray[base + l][c + addr] < ' ') {          buffer.charArray[base + l][c + addr] = ' ';          buffer.charAttributes[base + l][c + addr] = 0;          continue;        }        addr++;      }      if (addr > 0) {        String tmp = new String(buffer.charArray[base + l], c, addr);        // create new text node and make sure we insert &nbsp; (160)        Text text = new Text(tmp.replace(' ', (char) 160));        Element chunk = null;        if ((currAttr & 0xfff) != 0) {          if ((currAttr & VDUBuffer.BOLD) != 0)            chunk = addChunk(new Element("B"), chunk, text);          if ((currAttr & VDUBuffer.UNDERLINE) != 0)            chunk = addChunk(new Element("U"), chunk, text);          if ((currAttr & VDUBuffer.INVERT) != 0)            chunk = addChunk(new Element("I"), chunk, text);          if ((currAttr & buffer.COLOR_FG) != 0) {            String fg = color[((currAttr & buffer.COLOR_FG) >> 4) - 1];            Element font = new Element("FONT").setAttribute("COLOR", fg);            chunk = addChunk(font, chunk, text);          }          /*          if ((currAttr & buffer.COLOR_BG) != 0) {            Color bg = color[((currAttr & buffer.COLOR_BG) >> 8) - 1];          }          */        }        if (chunk == null) {          line.addContent(text);        } else {          line.addContent(chunk);        }      }      c += addr - 1;    }    return line;  }  /**   * Helper method to wrap a chunk or piece of text in another element.   * @param el the element to put the text or chunk into   * @param chunk a chunk of elements   * @param text a text element   * @return a new chunk made up from the element   */  private Element addChunk(Element el, Element chunk, Text text) {    if (chunk == null)      return el.addContent(text);    else      return el.addContent(chunk);  }  /**   * Set the VDUBuffer that contains the terminal screen and back-buffer   * @param buffer the terminal buffer   */  public void setVDUBuffer(VDUBuffer buffer) {    this.buffer = buffer;    if (simpleMode) {      this.buffer.setCursorPosition(0, 23);    }    this.buffer.setDisplay(this);    this.buffer.update[0] = true;  }  /**   * Get the current buffer.   * @return the VDUBuffer   */  public VDUBuffer getVDUBuffer() {    return buffer;  }}

⌨️ 快捷键说明

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