需要:将 Java 应用程序的日志输出到 GUI 组件中,例如 JTextArea。
关注点:需要以静态方式记录任何类的内容。但是,GUI 记录器组件不能是静态的(显然),因为它是父组件的成员。
我该怎么办?
创建一个单例日志提供程序并将“文本字段”添加为它的侦听器。
记录器单例的示例:
interface Listener {
void log(String log);
}
enum Logger {
instance;
private List<Listener> listeners = new LinkedList<Listener>();
public void addListener(Listener l) {
synchronized(listeners) {
listeners.add(l);
}
}
public void log(String log) {
synchronized(listeners) {
for(Listener l : listeners)
l.log(log);
}
}
}
像这样添加您的侦听器(您需要自己实现):
Logger.instance.addListener(myTextField);
并像这样使用它(来自任何类):
Logger.instance.log("Hello World!");
或者你可以使用像log4j这样的包。
记录到文件,让组件跟随文件的尾部。如果要将输出放入网格,则可能需要使用 log4j 的 XML 日志记录。
更新:您也可以实现一个内存循环记录器。
我想到了数据绑定。您需要一个代表您的日志的模型,并且该模型绑定到一个 GUI 组件。SWT 的一个通用数据绑定框架是 JFace 数据绑定,我确信 SWING 存在类似的东西。
它是如何工作的 - 记录器将消息添加到模型中,可能只是一个字符串数组列表(logentries)。每次模型更改时,数据绑定类都会监听模型并更新 GUI。它也可以反过来工作(可以将 GUI 上的编辑发送到模型),但您只需要一个方向。
注意你的类和包之间的循环依赖,你不想要意大利面条代码。
我的 Swing 应用程序包含 9 个模块(控制器、应用程序、平台、实用程序、模型、持久性、服务、记录器和视图)
以下是依赖项:
view -> logger, controller, utils, model
controller -> logger, application, model, utils
application -> service, model, utils, platform
service -> persistence, model, utils
platform -> model
utils -> no dependencies
model -> no dependencies
logger -> model, utils
所需的依赖关系是从视图到控制器,而不是从控制器到视图。
所以最好的方法是添加一个模块记录器并创建一个处理程序(它是一个可观察的)来通知观察者(JFrame 之类的视图,JFace = 观察者)。
视图和服务(您要触发观察者的地方)模块不相互依赖,而是通过记录器模块。
但我认为数据绑定器也可以这样工作。我想除了你依赖于框架。我的解决方案不是,所以如果我想从 Swing 切换到 swt,不用担心,我只是为 swt 实现它,我的业务逻辑保持不变。
你们都应该更明智地考虑设计。(并使用 Maven。)