Отправка сообщений на свинг JTextArea из разных мест - PullRequest
2 голосов
/ 28 ноября 2010

У меня всегда отображается JTextArea в главном окне моего приложения (если хотите, в журнале), и я хочу использовать его для отображения активности, происходящей в системе (например, вывод mock-debug, который вы делаете с System.out .println () если условия или что-то еще)

Я имею в виду высокоуровневые действия пользователя (например, «успешно загруженный файл» или «запись на диск», «завершение» и т. Д.)

Дело в том, что такие сообщения могут генерироваться где угодно в моей системе, в основном в другом пакете, классы которого имеют дело с данными и вычислениями, и они не знают о графическом интерфейсе.

Может быть, сохранить сообщения во временном файле, и текстовое поле «отслеживает» этот файл на предмет изменений, как это можно сделать?

Ответы [ 4 ]

5 голосов
/ 28 ноября 2010

Самый простой способ - определить интерфейс регистратора:

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

Затем передайте его компонентам, не относящимся к графическому интерфейсу, чтобы они не привязывались к конкретной реализации:

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 и т. Д.) И написать приложение, которое «пишет» в текстовый компонент.

0 голосов
/ 28 ноября 2010

Вы можете использовать EventBus , чтобы отделить ваш графический интерфейс от других частей вашего приложения. (В моем блоге есть еще введение ). Вы можете сделать что-то следующим образом:

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

0 голосов
/ 28 ноября 2010

Консоль сообщений может быть тем, что вы ищете.

Java также имеет API "Logger".

0 голосов
/ 28 ноября 2010

Дизайн может быть довольно сложным. Возможно, у вас может быть метод открытого доступа, например updateText (), в классе, где будет ваша TextArea. Затем вы создаете своего рода «ресурсный» или «разделяемый» класс (просто простой класс), который будет инициализирован вместе при запуске main (). Когда класс, содержащий вашу TextArea, создается, экземпляр помещается в «общий» класс (этот общий класс должен быть одноэлементным), и поэтому все другие классы вызывают этот «общий» класс (возможно, такой метод как updateTextArea ()) и он будет вызывать класс, содержащий TextArea, через этот экземпляр и вызывать TextArea для обновления текста.

...