Redirect output from System.out.println to JTextArea

5

I'm having trouble making this redirect, let's explain. I have a class called Engine.java , this class is responsible for doing my processing and it has all System.out.prints of the process, the problem is that now I created a window using Java Swing, and I would like to call it in that method, and I wanted all the System.out.print text to be JTextArea created by me. It's possible?

    
asked by anonymous 16.02.2016 / 20:46

1 answer

6

Yes we can!

Yes, you can change the System.out object that normally goes to the console using the System.setOut ". Just pass an instance of PrintStream that directs content to your TextArea .

One problem you may face is that the PrintStream constructor is given a OutputStream as its parameter.

So you will need to create a OutputStream to direct the written text, overwriting the write(byte) method, that is, it will have to work with bytes and not with String or characters.

One way to do this is by using a ByteArrayOutputStream to collect the written bytes and then transform them into String again.

Sample Code

Look at an example I made below:

PrintStream original = System.out;
StringBuilder sb = new StringBuilder();
System.setOut(new PrintStream(new OutputStream() {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    @Override
    public void write(int b) throws IOException {
        baos.write(b);
    }
    @Override
    public void flush() throws IOException {
        sb.append(baos.toString());
        baos.reset();
    }
    @Override
    public void close() throws IOException {
        sb.append(baos.toString());
        baos.reset();
    }
}, true));

//tudo o que for escrito será capturado
System.out.print("Capture ");
System.out.println("Isto ");
System.out.format("Para %s!", "Mim");

//restaurando o original para escrever no console
System.setOut(original);
System.out.format("Resultado capturado:%n%s", sb);

Basically, I did an implementation of OutputStream as I mentioned above, which saves the data in a byte array.

When flush or close occurs, the code adds the data to StringBuilder . In your case, just change this to concatenate TextArea .

Note that I passed a second parameter to the PrintStream constructor with the value true . This causes the flush method to be called every time something is written to PrintStream . If you do not put this in, the data will not be displayed until the buffer is full because PrintStream uses BufferedOutputStream internally, and some information may not be displayed in your TextArea when you expect it.

An alert

It is not considered good practice to write in System.out .

If your program is more than an exercise or academic project, you should use a log library such as Logback or Log4J.

These libraries are much more flexible and allow you to configure what data will be placed in the log, in what format, etc.

    
17.02.2016 / 04:01