📄 appterm.java
字号:
package org.xmlBlaster.contrib;import java.awt.Color;import java.awt.EventQueue;import java.awt.Font;import java.awt.GraphicsEnvironment;import java.awt.GridLayout;import java.awt.Rectangle;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.PrintStream;import java.lang.reflect.Method;// import java.util.concurrent.ArrayBlockingQueue;// import java.util.concurrent.TimeUnit;import EDU.oswego.cs.dl.util.concurrent.BoundedBuffer;import java.util.HashMap;import java.util.Map;import java.util.StringTokenizer;import java.util.logging.Logger;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextPane;import javax.swing.text.BadLocationException;import javax.swing.text.Document;import javax.swing.text.MutableAttributeSet;import javax.swing.text.SimpleAttributeSet;import javax.swing.text.StyleConstants;/** * * AppTerm is an application which invokes a java class main method and redirects the System.in and * System.out to a graphical window. XmlBlaster colorful logging are supported. * * @author <a href="mailto:michele@laghi.eu">Michele Laghi</a> */public class AppTerm extends JFrame implements KeyListener { public static final String END = "\033[0m"; public static final String ESC = "\033["; private final static Color[] COLORS = new Color[] { Color.BLACK, Color.RED, Color.GREEN, Color.YELLOW, Color.BLUE, Color.PINK, Color.LIGHT_GRAY, Color.WHITE}; Logger log = Logger.getLogger(AppTerm.class.getName()); public class AsyncWriter implements Runnable { private Document doc; private int maxSize; private int sizeToFlush; private String txt; private MutableAttributeSet attr; private JTextPane pane; public AsyncWriter(String txt, JTextPane pane, Document doc, int maxSize, int sizeToFlush, MutableAttributeSet attr) { this.pane = pane; this.doc = doc; this.maxSize = maxSize; this.txt = txt; this.attr = attr; this.sizeToFlush = sizeToFlush; } public void run() { try { int end = this.doc.getLength() - 1; if (end < 0) end = 0; this.doc.insertString(end, txt, attr); end = this.doc.getLength(); if (end > this.maxSize) { this.doc.remove(0, this.sizeToFlush); } end = this.doc.getLength() - 1; if (end < 0) end = 0; this.pane.setCaretPosition(end); } catch (BadLocationException ex) { ex.printStackTrace(); } } } public class PanelStream extends OutputStream { StringBuffer buf = new StringBuffer(128); private Document doc; private JTextPane pane; MutableAttributeSet attr; boolean inStyle; Map styles = new HashMap(); int maxSize; int sizeToFlush; public PanelStream(JTextPane pane, int maxSize) { this.pane = pane; this.doc = pane.getDocument(); this.maxSize = maxSize; this.sizeToFlush = (int)(0.8 * maxSize); } private Color getColor(String txt, int offset) { try { int col = Integer.parseInt(txt) - offset; if (col < 0 || col > 7) return null; return COLORS[col]; } catch (Throwable ex) { return null; } } private MutableAttributeSet registerNewStyle(String token) { String tmp1 = token.substring(2, 4); String tmp2 = token.substring(5, 7); Color foreground = getColor(tmp1, 30); Color background = getColor(tmp2, 40); if (foreground == null) foreground = Color.WHITE; if (background == null) background = Color.BLACK; MutableAttributeSet newAttr = new SimpleAttributeSet(); StyleConstants.setForeground(newAttr, foreground); StyleConstants.setBackground(newAttr, background); // StyleConstants.setBold(newAttr, true); return newAttr; } private void setStyle(String token) { this.attr = (MutableAttributeSet)this.styles.get(token); if (this.attr == null) this.attr = registerNewStyle(token); this.inStyle = true; } private final void inNormalText(String in) { int pos = in.indexOf(ESC); if (pos > -1) { String pre = in.substring(0, pos); writeToDoc(pre); String token = in.substring(pos, pos + 8); in = in.substring(pos + 8); setStyle(token); filter(in); } else writeToDoc(in); } private final void inStyledText(String in) { int pos = in.indexOf(END); if (pos > -1) { String pre = in.substring(0, pos); writeToDoc(pre); in = in.substring(pos + 4); this.attr = null; this.inStyle = false; filter(in); } else writeToDoc(in); } private final void filter(String in) { if (in == null || in.length() < 1) return; if (this.inStyle) inStyledText(in); else inNormalText(in); } private final void writeToDoc(String txt) { if (txt == null) return; EventQueue.invokeLater(new AsyncWriter(txt, pane, this.doc, this.maxSize, this.sizeToFlush, this.attr)); } public void write(int b) throws IOException { this.buf.append((char)b); if (b == 10) { filter(this.buf.toString()); this.buf = new StringBuffer(128); } } } public class PanelInputStream extends InputStream { private BoundedBuffer queue; // private ArrayBlockingQueue queue; public PanelInputStream(int maxSize) { // boolean orderedFIFO = true; // this.queue = new ArrayBlockingQueue(maxSize, orderedFIFO); this.queue = new BoundedBuffer(maxSize); } public void write(int val) { try { this.queue.put(new Integer(val)); // hack to force the read in readLine to break. Otherwise readLine will // not return. This has not been tested on windows. if (val == 10) this.queue.put(new Integer(-1)); } catch (InterruptedException ex) { ex.printStackTrace(); } } public int read() throws IOException { Object obj = null; try { while (obj == null) { obj = this.queue.poll(5L /*, TimeUnit.SECONDS*/); } } catch (InterruptedException ex) { throw new IOException("Interrupted Exception occured: " + ex.getMessage()); } int val = ((Integer)obj).intValue(); return val; } /** * This is not really needed but may help for performance. */ public int available() throws IOException { return this.queue.size(); } } /** * */ private static final long serialVersionUID = 1L; private JTextPane pane; PanelInputStream panelInputStream = new PanelInputStream(2048); public AppTerm() { super("Horizontal Box Test Frame"); } private int getInt(String val, int def) { try { return Integer.parseInt(val); } catch (Throwable ex) { log.warning("could not parse value '" + val + "' since not an integer. Will take its default '" + def + "'"); return def; } } private void setFont() { String fontProp = System.getProperty("font"); if (fontProp != null) { StringTokenizer tokenizer = new StringTokenizer(fontProp.trim(), ","); if (!tokenizer.hasMoreElements()) return; String fontName = tokenizer.nextToken().trim(); if (!tokenizer.hasMoreElements()) return; try { int size = Integer.parseInt(tokenizer.nextToken().trim()); Font newFont = new Font(fontName, Font.PLAIN, size); this.pane.setFont(newFont); } catch (Exception ex) { ex.printStackTrace(); } } } public void init(String[] args) { setBounds(getBounds(args)); JPanel box = new JPanel(); // Use BoxLayout.Y_AXIS below if you want a vertical box box.setLayout(new GridLayout(1,1)); setContentPane(box); this.pane = new JTextPane(); this.pane.setBackground(getColor(args)); JScrollPane pane = new JScrollPane(this.pane); // this.pane.setBorder(BorderFactory.createRaisedBevelBorder()); this.pane.setAutoscrolls(true); // this.pane.setLineWrap(true); String name = args[0]; this.setTitle(name); setFont(); this.pane.setName(name); this.pane.setToolTipText(name); box.add(pane); // box.add(this.pane); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); PanelStream panelStream = new PanelStream(this.pane, 1024*1024); System.setErr(new PrintStream(panelStream)); System.setOut(new PrintStream(panelStream)); System.setIn(this.panelInputStream); this.pane.addKeyListener(this); loadAppl(args); System.out.println("END OF INIT"); } private Rectangle getBounds(String[] args) { if (args.length < 5) return new Rectangle(0, 0, 800, 600); return new Rectangle(getInt(args[1], 0), getInt(args[2], 0), getInt(args[3], 800), getInt(args[4], 600)); } private Color getColor(String[] args) { try { return Color.decode(args[5]); } catch (Throwable ex) { log.severe("Error when trying to decode the color '" + args[5] + "'"); return Color.WHITE; } } private void loadAppl(String[] args) { try { String className = args[6]; // URLClassLoader urlClassLoader = URLClassLoader.newInstance(null, ClassLoader.getSystemClassLoader()); ClassLoader classLoader = ClassLoader.getSystemClassLoader(); Class clazz = classLoader.loadClass(className); Object obj = clazz.newInstance(); Method main = clazz.getDeclaredMethod("main", new Class[] {String[].class }); String[] vals = stripArgs(args); main.invoke(obj, new Object[] { vals }); } catch (Exception ex) { ex.printStackTrace(); } } private String[] stripArgs(String[] args) { int offs = 7; if (args.length < (offs+1)) return new String[0]; int nmax = args.length -offs; String[] ret = new String[nmax]; for (int i=0; i < ret.length; i++) ret[i] = args[i+offs]; return ret; } public void keyPressed(KeyEvent e) { char c = e.getKeyChar(); this.panelInputStream.write(c); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } // java org.xmlBlaster.contrib.AppTerm XMLBLASTER 0 100 1500 500 192192192 org.xmlBlaster.Main public static void main(String args[]) { if (args.length < 1) { System.err.println("usage: " + AppTerm.class.getName() + " title x0 y0 width height color className [args]"); System.err.println("Example: java org.xmlBlaster.contrib.AppTerm XMLBLASTER 0 100 1500 500 192192192 org.xmlBlaster.Main"); Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); System.err.println("Fonts recognized by this system: "); for (int i=0; i < fonts.length; i++) System.err.println(fonts[i].getName()); System.exit(-1); } try { AppTerm bt = new AppTerm(); bt.init(args); } catch (Exception ex) { ex.printStackTrace(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -