如何使用线程同步重绘自定义控制台?

时间:2011-10-03 11:13:38

标签: multithreading swing console log4

我有一个JScrollPane(包含文本区域),充当我的swing应用程序的自定义控制台。这是我的控制台的代码

    class InternalConsoleFrame{
    static JTextArea outArea    
    static JScrollPane consoleHolder

    static setUpStreams(){
        outArea = new javax.swing.JTextArea(10,100)
        System.setErr(new PrintStream(new JTextAreaOutputStream(outArea)));
        System.setOut(new PrintStream(new JTextAreaOutputStream(outArea)));
        WriterAppender logAppender = new WriterAppender(new PatternLayout(), new JTextAreaOutputStream(outArea));
        Logger.getRootLogger().addAppender(logAppender);        
    }

    public InternalConsoleFrame(){

        DefaultCaret caret = (DefaultCaret)outArea.getCaret();
        caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);

        outArea.setBackground(new Color(255,250,205));
        outArea.setForeground(Color.BLACK);
        outArea.setLineWrap(true);
        outArea.setWrapStyleWord(true);
        outArea.setFont(new Font(null, Font.PLAIN, 13));
        outArea.addMouseListener(new ConsolePopup());
        consoleHolder = new JScrollPane(outArea);

    }    

}

public class JTextAreaOutputStream extends OutputStream {
    JTextArea ta;

    JTextAreaOutputStream(javax.swing.JTextArea t) {
        super();
        ta = t;
    }

    public synchronized void write(int i) {
        ta.append(Character.toString((char)i));

    }

    public synchronized void write(char[] buf, int off, int len) {
        String s = new String(buf, off, len);
        ta.append(s);

    }

}

后端的API服务器是连续打印状态(使用后端的println / lo4j)但我的自定义控制台无法同步捕获log4j / print语句并重新绘制自身。

只有在API调用完成后才会从后端删除整个log4j语句集。我希望我的控制台捕获后端log4j / println语句在API调用期间并重新绘制自身。如何实现这一目标?

我的猜测是创建的InternalConsoleFrame()对象被本机swing awt线程阻塞,直到完成API调用的执行。如果是这种情况,我认为我需要将上面的代码片段发布到新的Thread上。如果是这样,我应该在上面代码的哪一部分实现线程。我很困惑......请帮忙..

1 个答案:

答案 0 :(得分:1)

同意,看起来你通过违反Swing的基本线程规则来阻止event dispatch thread(EDT):所有组件访问必须在EDT上发生。实现一个SwingWorker来实现它,它的api doc有一些例子,another recently discussed这里