免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1214 | 回复: 0
打印 上一主题 下一主题

做自己的控制台 console [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-21 19:03 |只看该作者 |倒序浏览

                                最近在和几个java高手一起做几个javaIDE,不过是简略版本的,我主要负责的是将编译程序的结果输出到我们的“控制台”(其实是一个JTEXTPANE)上,其中遇到了一些麻烦,因为毕竟我的java很菜,所以了,到处查资料,终于了解到了利用重定向System.out 和System.err到JTextPane就可以了。成功后心情很是爽啊,呵呵,现在将这个测试的代码贴上来和大家共享。
  
  
import java.awt.*;   
import java.io.*;   
  
import javax.swing.*;   
import javax.swing.text.*;   
  
/**  
*
*/  
public class ConsolePane extends JScrollPane {   
  
    private JTextPane textPane = new JTextPane();   
  
    private static ConsolePane console = null;   
  
    public static synchronized ConsolePane getInstance() {   
        if (console == null) {   
            console = new ConsolePane();   
        }   
        return console;   
    }   
  
    private ConsolePane() {   
  
        setViewportView(textPane);   
  
        // Set up System.out   
        PrintStream mySystemOut = new MyPrintStream(System.out, Color.BLACK);   
        System.setOut(mySystemOut);   
  
        // Set up System.err   
        PrintStream mySystemErr = new MyPrintStream(System.err, Color.RED);   
        System.setErr(mySystemErr);   
           
        textPane.setEditable(true);   
        setPreferredSize(new Dimension(640, 120));   
    }   
  
    /**  
     * Returns the number of lines in the document.  
     */  
    private final int getLineCount() {   
        return textPane.getDocument().getDefaultRootElement().getElementCount();   
    }   
  
    /**  
     * Returns the start offset of the specified line.  
     * @param line  The line  
     * @return The start offset of the specified line, or -1 if the line is  
     *         invalid  
     */  
    private int getLineStartOffset(int line) {   
        Element lineElement = textPane.getDocument().getDefaultRootElement()   
                .getElement(line);   
        if (lineElement == null)   
            return -1;   
        else  
            return lineElement.getStartOffset();   
    }   
  
    /**  
     * 清除超过行数时前面多出行的字符  
     */  
    private void replaceRange(String str, int start, int end) {   
        if (end  start) {   
            throw new IllegalArgumentException("end before start");   
        }   
        Document doc = textPane.getDocument();   
        if (doc != null) {   
            try {   
                if (doc instanceof AbstractDocument) {   
                    ((AbstractDocument) doc).replace(start, end - start, str,   
                            null);   
                } else {   
                    doc.remove(start, end - start);   
                    doc.insertString(start, str, null);   
                }   
            } catch (BadLocationException e) {   
                throw new IllegalArgumentException(e.getMessage());   
            }   
        }   
    }   
  
    class MyPrintStream extends PrintStream {   
  
        private Color foreground; //输出时所用字体颜色   
           
        /**  
         * 构造自己的 PrintStream  
         * @param out 可传入 System.out 或 System.err, 实际不起作用  
         * @param foreground 显示字体颜色  
         */  
        MyPrintStream(OutputStream out,Color foreground) {   
            super(out,true); //使用自动刷新   
            this.foreground = foreground;   
        }   
  
        /**  
         * 在这里重截,所有的打印方法都要调用最底一层的方法  
         */  
        public void write(byte[] buf, int off, int len) {   
            final String message = new String(buf, off, len);   
  
            /** SWING非界面线程访问组件的方式 */  
            SwingUtilities.invokeLater(new Runnable() {   
                public void run() {   
                    try {   
  
                        StyledDocument doc = (StyledDocument) textPane   
                                .getDocument();   
  
                        // Create a style object and then set the style   
                        // attributes   
                        Style style = doc.addStyle("StyleName", null);   
  
                        // Foreground color   
                        StyleConstants.setForeground(style, foreground);   
  
                        doc.insertString(doc.getLength(), message, style);   
  
                    } catch (BadLocationException e) {   
                        // e.printStackTrace();   
                    }   
  
                    // Make sure the last line is always visible   
                    textPane.setCaretPosition(textPane.getDocument()   
                            .getLength());   
  
                    // Keep the text area down to a certain line count   
                    int idealLine = 150;   
                    int maxExcess = 50;   
  
                    int excess = getLineCount() - idealLine;   
                    if (excess >= maxExcess) {   
                        replaceRange("", 0, getLineStartOffset(excess));   
                    }   
                }   
            });   
        }   
    }   
}   
把 System.out 和 System.err 重定向到 JTextArea 的做法在网上能找到不少,由于 JTextArea 不能用不同的字体分别显示内容。但我还是希望能象 Eclipse 控制台那样,标准输出为黑色,错误信息为红色,于是选择了 JTextPane 作为输出目的地。线程之间通信息用到了 PipedInputStream 、PipedOutputStream 和 SwingUtilities.invokeLater(new Runnable())。
自定义了一个 JScrollPane,类名为 ConsolePane,写成的单例类;使用时只需要在你的面板上加上 ConsolePane组件,例如:[color="#ff3366"]getContentPane().add(ConsolePane.getInstance(), BorderLayout.CENTER);
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/104183/showart_2100110.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP