📄 swingterminal.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.terminal;import javax.swing.JScrollBar;import java.awt.AWTEvent;import java.awt.AWTEventMulticaster;import java.awt.Color;import java.awt.Component;import java.awt.Dimension;import java.awt.Font;import java.awt.FontMetrics;import java.awt.Graphics;import java.awt.Image;import java.awt.Insets;import java.awt.Point;import java.awt.event.AdjustmentEvent;import java.awt.event.AdjustmentListener;import java.awt.event.FocusEvent;import java.awt.event.FocusListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;/** * Video Display Unit emulation for Swing/AWT. This class implements all necessary * features of a character display unit, but not the actual terminal emulation. * It can be used as the base for terminal emulations of any kind. * <P> * This is a lightweight component. It will render very badly if used * in standard AWT components without overloaded update() method. The * update() method must call paint() immediately without clearing the * components graphics context or parts of the screen will simply * disappear. * <P> * <B>Maintainer:</B> Matthias L. Jugel * * @version $Id: SwingTerminal.java,v 2.2 2003/04/27 16:36:45 marcus Exp $ * @author Matthias L. Jugel, Marcus Mei遪er */public class SwingTerminal extends Component implements VDUDisplay, KeyListener, MouseListener, MouseMotionListener { private final static int debug = 0; /** the VDU buffer */ private VDUBuffer buffer; /** lightweight component definitions */ private final static long VDU_EVENTS = AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.ACTION_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK; private Insets insets; /* size of the border */ private boolean raised; /* indicator if the border is raised */ private Font normalFont; /* normal font */ private FontMetrics fm; /* current font metrics */ private int charWidth; /* current width of a char */ private int charHeight; /* current height of a char */ private int charDescent; /* base line descent */ private int resizeStrategy; /* current resizing strategy */ private Point selectBegin, selectEnd; /* selection coordinates */ private String selection; /* contains the selected text */ private JScrollBar scrollBar; private SoftFont sf = new SoftFont(); private boolean colorPrinting = false; /* print display in color */ private Image backingStore = null; /** * Create a color representation that is brighter than the standard * color but not what we would like to use for bold characters. * @param clr the standard color * @return the new brighter color */ private Color brighten(Color clr) { int r,g,b; r = (int) min(clr.getRed() * 1.2, 255.0); g = (int) min(clr.getGreen() * 1.2, 255.0); b = (int) min(clr.getBlue() * 1.2, 255.0); return new Color(r, g, b); } /** * Create a color representation that is darker than the standard * color but not what we would like to use for bold characters. * @param clr the standard color * @return the new darker color */ private Color darken(Color clr) { int r,g,b; r = (int) max(clr.getRed() * 0.8, 0.0); g = (int) max(clr.getGreen() * 0.8, 0.0); b = (int) max(clr.getBlue() * 0.8, 0.0); return new Color(r, g, b); } /** A list of colors used for representation of the display */ private Color color[] = {Color.black, Color.red, Color.green, Color.yellow, Color.blue, Color.magenta, Color.cyan, Color.white, null, // bold color null, // inverted color }; public final static int RESIZE_NONE = 0; public final static int RESIZE_FONT = 1; public final static int RESIZE_SCREEN = 2; public final static int COLOR_BOLD = 8; public final static int COLOR_INVERT = 9; /* definitions of standards for the display unit */ private final static int COLOR_FG_STD = 7; private final static int COLOR_BG_STD = 0; /** User defineable cursor colors */ private Color cursorColorFG = null; private Color cursorColorBG = null; protected double max(double f1, double f2) { return (f1 < f2)?f2:f1; } protected double min(double f1, double f2) { return (f1 < f2)?f1:f2; } /** * Create a new video display unit with the passed width and height in * characters using a special font and font size. These features can * be set independently using the appropriate properties. * @param buffer a VDU buffer to be associated with the display * @param font the font to be used (usually Monospaced) */ public SwingTerminal(VDUBuffer buffer, Font font) { setVDUBuffer(buffer); addKeyListener(this); /* we have to make sure the tab key stays within the component */ String version = System.getProperty("java.version"); if (version.startsWith("1.4")) { try { Class params[] = new Class[]{boolean.class}; SwingTerminal.class.getMethod("setFocusable", params).invoke(this, new Object[]{new Boolean(true)}); SwingTerminal.class.getMethod("setFocusTraversalKeysEnabled", params).invoke(this, new Object[]{new Boolean(false)}); } catch (Exception e) { System.err.println("vt320: unable to reset focus handling for java version " + version); e.printStackTrace(); } } // lightweight component handling enableEvents(VDU_EVENTS); // set the normal font to use setFont(font); // set the standard resize strategy setResizeStrategy(RESIZE_FONT); setForeground(Color.white); setBackground(Color.black); cursorColorFG = color[COLOR_FG_STD]; cursorColorBG = color[COLOR_BG_STD]; clearSelection(); addMouseListener(this); addMouseMotionListener(this); selection = null; } /** * Create a display unit with size 80x24 and Font "Monospaced", size 12. */ public SwingTerminal(VDUBuffer buffer) { this(buffer, new Font("Monospaced", Font.PLAIN, 11)); } /** * Set a new terminal (VDU) buffer. * @param buffer new buffer */ public void setVDUBuffer(VDUBuffer buffer) { this.buffer = buffer; buffer.setDisplay(this); } /** * Return the currently associated VDUBuffer. * @return the current buffer */ public VDUBuffer getVDUBuffer() { return buffer; } /** * Set new color set for the display. * @param colorset new color set */ public void setColorSet(Color[] colorset) { System.arraycopy(colorset, 0, color, 0, 10); buffer.update[0] = true; redraw(); } /** * Get current color set. * @return the color set currently associated */ public Color[] getColorSet() { return color; } /** * Set the font to be used for rendering the characters on screen. * @param font the new font to be used. */ public void setFont(Font font) { super.setFont(normalFont = font); fm = getFontMetrics(font); if (fm != null) { charWidth = fm.charWidth('@'); charHeight = fm.getHeight(); charDescent = fm.getDescent(); } if (buffer.update != null) buffer.update[0] = true; redraw(); } /** * Set the strategy when window is resized. * RESIZE_FONT is default. * @param strategy the strategy * @see #RESIZE_NONE * @see #RESIZE_FONT * @see #RESIZE_SCREEN */ public void setResizeStrategy(int strategy) { resizeStrategy = strategy; } /** * Set the border thickness and the border type. * @param thickness border thickness in pixels, zero means no border * @param raised a boolean indicating a raised or embossed border */ public void setBorder(int thickness, boolean raised) { if (thickness == 0) insets = null; else insets = new Insets(thickness + 1, thickness + 1, thickness + 1, thickness + 1); this.raised = raised; } /** * Connect a scrollbar to the VDU. This should be done differently * using a property change listener. * @param scrollBar the scroll bar */ public void setScrollbar(JScrollBar scrollBar) { if (scrollBar == null) return; this.scrollBar = scrollBar; this.scrollBar.setValues(buffer.windowBase, buffer.height, 0, buffer.bufSize - buffer.height); this.scrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { buffer.setWindowBase(evt.getValue()); } }); } /** * Redraw marked lines. */ public void redraw() { if (backingStore != null) { redraw(backingStore.getGraphics()); repaint(); } } protected void redraw(Graphics g) { if (debug > 0) System.err.println("redraw()"); int xoffset = (super.getSize().width - buffer.width * charWidth) / 2; int yoffset = (super.getSize().height - buffer.height * charHeight) / 2; int selectStartLine = selectBegin.y - buffer.windowBase; int selectEndLine = selectEnd.y - buffer.windowBase; Color fg = darken(color[COLOR_FG_STD]); Color bg = darken(color[COLOR_BG_STD]); g.setFont(normalFont); /* for debug only if (update[0]) { System.err.println("Redrawing all"); } else { for (int l = 1; l < size.height+1; l++) { if (update[l]) { for (int c = 0; c < size.height-l;c++) { if (!update[c+l]) { System.err.println("Redrawing "+(l-1)+" - "+(l+c-2)); l=l+c; break; } } } } } */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -