2

我有一个 JTextArea 在我的主应用程序窗口中始终可见(如果你愿意,可以是一个日志),我想用它来显示系统中正在进行的活动(比如你用 System.out.println( ) 在 if 条件或其他条件下)

我的意思是用户所做的高级事情,(如“成功加载文件”或“写入磁盘”、“完成”等)

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

也许将消息保存到一个临时文件和文本区域“监控”该文件的更改,这怎么做?

4

4 回答 4

5

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

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 等)并编写一个“写入”文本组件的附加程序。

于 2010-11-28T16:43:40.170 回答
0

您可以使用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");
    }

}

在实际系统中,您可能希望将主题声明移至另一个类,以便人们可以使用它而不受特定实现的束缚。例如,您可以有一个仅包含主题的静态字符串常量的主题类。然后,您可以拥有多个类来监听这些主题并处理消息(例如,除了 jtextarea 组件之外,您还可以拥有一个标准的日志框架,它可以写入日志文件)。

于 2010-11-28T20:03:47.737 回答
0

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

于 2010-11-28T16:30:53.307 回答
0

消息控制台可能是您正在寻找的。

Java 也有一个“记录器”API。

于 2010-11-28T16:30:54.360 回答