Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write logger message to file and textarea while maintaining default behaviour in Java

I'm currently working on logging messages from my application in .log files. This is working fine so far but now I'm trying to output the same message to a textarea. I have been using the default logger for all this.

This so that I have one class that does all the work of logging to a .log file and writing the same output to a textarea for the admin to see.

This is a Java swing JFrame application containing just a textarea (all I need). There is a bunch going on in the background and all of that activity has to be logged for review/debugging.

I've been having trouble finding a good example so I was wondering if you guys could help me.

like image 776
Orion Avatar asked May 28 '12 13:05

Orion


2 Answers

In your case, since you are using JDK default logging, your option is to write your own java.util.Handler and implement the publish method. Somewhat like this:

public class TextAreaHandler extends java.util.logging.Handler {

    private JTextArea textArea = new JTextArea(50, 50);

    @Override
    public void publish(final LogRecord record) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                StringWriter text = new StringWriter();
                PrintWriter out = new PrintWriter(text);
                out.println(textArea.getText());
                out.printf("[%s] [Thread-%d]: %s.%s -> %s", record.getLevel(),
                        record.getThreadID(), record.getSourceClassName(),
                        record.getSourceMethodName(), record.getMessage());
                textArea.setText(text.toString());
            }

        });
    }

    public JTextArea getTextArea() {
        return this.textArea;
    }

    //...
}

Then, you can get the text area from your handler in your Swing application, somewhat like:

for(Handler handler: logger.getHandlers()){
    if(handler instanceof TextAreaHandler){
        TextAreaHandler textAreaHandler = (TextAreaHandler) handler;
        getContentPane().add(textAreaHandler.getTextArea());
    }
}

Then, you make sure your logging.properties file contains the configuration of your new handler:

hackers.logging.TestDrive.level=INFO
hackers.logging.TestDrive.handlers=hackers.logging.TextAreaHandler

And, if you are not going to put this configuration in your default logging.properties file (located in your JRE lib folder) then make sure to provide the path to your customized logging.properties file in a property at application startup:

java -Djava.util.logging.config.file=my-customized-logging.properties ...
like image 199
Edwin Dalorzo Avatar answered Nov 15 '22 11:11

Edwin Dalorzo


Just extends from StreamHandler - this is how ConsoleHandler and FileHandler works. And, override the publish function:

public class TextAreaHandler extends StreamHandler {
    JTextArea textArea = null;

    public void setTextArea(JTextArea textArea) {
        this.textArea = textArea;
    }

    @Override
    public void publish(LogRecord record) {
        super.publish(record);
        flush();

        if (textArea != null) {
            textArea.appendText(getFormatter().format(record));
        }
    }
}

Set the output place first before logging message, for example:

public TextAreaHandler textAreaHandler = new TextAreaHandler();
textAreaHandler.setTextArea(<your JTextArea control>);
like image 25
Thach Van Avatar answered Nov 15 '22 11:11

Thach Van