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

发布于 2024-12-07 22:09:54 字数 1866 浏览 0 评论 0原文

我有一个 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 语句。我希望我的控制台在 API 调用期间捕获后端 log4j/println 语句并重新绘制自身。如何才能实现这一目标?

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

I have a JScrollPane(packed with text area) that acts as a custom console for my swing application. Here is the code for my console

    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);

    }

}

The API server at the back end is continuously printing status (using println/lo4j from backend) but my custom console is not able to synchronously capture the log4j/print statements and repaint itself.

It drops the whole set of log4j statements from the backend only after the total completion of the API call. I want my console to capture the backend log4j/println statements During the API call and repaint itself. How can this be achieved?

My guess is that the InternalConsoleFrame() object created is being blocked by the native swing awt thread until the complete execution of the API call. If this is the case, I think that I need to launch the above code snippet onto a new Thread. If so, in which portion of the above code should I implement threading. I am quite confused..Please help..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

箜明 2024-12-14 22:09:54

同意,看来您正在阻止 事件调度线程(EDT) 违反了 Swing 的基本线程规则:所有组件访问必须发生在 EDT 上。实现一个 SwingWorker 来实现这一点,它的 api 文档有一些示例,另一个最近讨论的在这里

Agreed, it looks like you're blocking the event dispatch thread(EDT) by violating the base threading rule for Swing: all component access must happen on the EDT. Implement a SwingWorker to achieve that, its api doc has some examples, another recently discussed here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文