繁体   English   中英

从不同的地方向Swing JTextArea发送消息

[英]Sending messages to a swing JTextArea from different places

我有一个JTextArea在我的主应用程序窗口中始终可见(如果需要,则为Log),并且我想用它来显示系统中正在进行的活动(例如您将对System.out.println( )在条件或其他条件下

我指的是用户所做的高级操作(例如“成功加载文件”或“写入磁盘”,“完成”等)

这样的消息可以在我的系统中的任何地方生成,主要是在另一个包中,这些包的类处理数据和计算,并且它们不知道GUI。

也许将消息保存到临时文件中,然后将textarea“监视器”保存到该文件中以进行更改,该怎么做?

最简单的方法是定义记录器接口:

package com.example.logging;
public interface ActivityLogger {
    void logAction(String message);
}

然后将其传递给您的非GUI组件,这样它们就不会与特定的实现挂钩:

public class FileLoader {

    private ActivityLogger logger;
    public FileLoader(ActivityLogger logger){
        this.logger = logger;
    }

    public void loadFile(){
        // load stuff from file
        logger.logAction("File loaded successfully");
    }

}

现在,进行写入文本组件的实现很简单:

public class TextComponentLogger implements ActivityLogger{
    private final JTextComponent target;
    public TextComponentLogger(JTextComponent target) {
        this.target = target;
    }

    public void logAction(final String message){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                target.setText(String.format("%s%s%n", 
                                             target.getText(),
                                             message));
            }
        });
    }
}
// Usage:
JTextArea logView = new JTextArea();
TextComponentLogger logger = new TextComponentLogger(logView);
FileLoader fileLoader = new FileLoader(logger);
fileLoader.loadFile();

当然,您也可以使用标准的日志记录框架(java.util.logging,slf4j,log4j等),并编写一个“写入”文本组件的附加程序。

设计可能相当复杂。 也许在TextArea所在的类中可以有一个像updateText()这样的公共访问方法。 然后,您将创建一种“资源”或“共享”类(仅是普通类),当您运行main()时将它们一起初始化。 创建包含TextArea的类时,会将一个实例放入“共享”类(此共享类应为单例),因此所有其他类都将其称为“共享”类(也许是诸如updateTextArea()之类的方法)然后通过该实例调用包含TextArea的类,并调用TextArea更新文本。

消息控制台可能就是您想要的。

Java还具有“记录器” API。

您可以使用EventBus将GUI与应用程序的其他部分分离。 (我的博客有另一个介绍 )。 您可以执行以下操作:

public class LogArea extends JTextArea {
    public static final String LOG_TOPIC = "logarea_topic";

    public LogArea() {
        super();
        // Read in the annotations, register self as a listener to the topic
        AnnotationProcessor.process(this);
    }

    @EventTopicSubscriber(topic=LOG_TOPIC)
    public void logEvent(String topic, String text) {
        append(text + "\n");
    }

}

public class DomainClass {

    public void foo() {
        // Send out a notification throughout the system to whichever components
        // are registered to handle this topic.
        EventBus.publish(LogArea.LOG_TOPIC, "some text you want to appear in the log area");
    }

}

在真实的系统中,您可能希望将主题声明移至另一类,以便一个人可以使用它而不依赖于特定的实现。 例如,您可能有一个Topics类,只包含主题的静态字符串常量。 然后,您可以有多个类来侦听这些主题并处理消息(例如,除了jtextarea组件之外,您可以拥有一个标准的日志记录框架,该框架可以写出到日志文件中)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM