If you want to get fancy, you can reroute System.Out
to your own PrintStream
using System.setOut(PrintStream out)
. At that point you can read that PrintStream
using a InputStreamReader
. That InputStreamReader
can then populate your GUI.
This isn't exactly the recommended fashion of communicating within a JVM, but if that's what your library gives you, I guess that's what you have to work with.
But keep in mind, if you reroute System.Out
, all methods using System.Out
will use the new PrintStream
. That means nothing will get printed to your console anymore.
Here's an example of what I'm talking about:
import java.io.*;
import java.util.Arrays;
import javax.swing.*;
public class StandardOutReader extends JPanel{
JTextArea textArea = new JTextArea();
public StandardOutReader(){
add(textArea);
try {
//create all your inputs/outputs
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);
System.setOut(new PrintStream(out));
final InputStreamReader reader = new InputStreamReader(in);
//A thread that will continuously read the reader, and post the output to the GUI
new Thread(new Runnable(){
@Override
public void run() {
try {
char[] cBuffer = new char[256]; //Buffer for reading
int bytesRead; // number of byts read in the last "read()" call
while((bytesRead = reader.read(cBuffer)) != -1){
//Copy over only the interesting bytes
final char[] copy = Arrays.copyOf(cBuffer, bytesRead);
//Tell the GUI to update
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
textArea.append(new String(copy));
}});
}
} catch (IOException e) {
e.printStackTrace();
} finally{
//Closing the reader
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new StandardOutReader());
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//Thread that randomly prints stuff. Not part of the GUI stuff at all.
new Thread(new Runnable(){
@Override
public void run() {
for(int i = 0; i < 10; i++){
try {
Thread.sleep((long)(4000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Adding another phrase");
}
}}).start();
}
}