簡體   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