I have a GUI application that process some data, it converts line of text to an object. Each object that is created is shown on a JTextPane ot JTextArea. example:
Line # 1 created 827401830
Line # 2 created 827401831
So the user is inform of the process.
Behind the scene, there’s a thread that runs in the background and does all the work. The problem is that one of the fields of this thread has is a JTextArea. and it looks like this:
public class ConsumerThread implements Runnable
{
private ArrayBlockingQueue<TicketExchangeLine> queue;
private JTextArea textArea;
public ExchConsumerThread(ArrayBlockingQueue<TicketExchangeLine> queue, JTextArea textArea)
{
this.queue = queue;
this.textArea = textArea;
}
public void run()
{
try
{
while (true)
{
// check if end of file from producer POV
if (queue.peek()!=null && ...)
break;
MyObject obj = queue.take();
try{
//do the process here
textArea.append("here comes the output for the user..."+obj.getID);
}catch(Exception nfe)
{
//Oops
}
}
textArea.append("\nDone!");
}catch (InterruptedException e)
{
// Oops
}catch(Exception exp)
{
exp.printStackTrace();
}
}
}
So the code above works fine and does the job but sometimes I’m using this thread not from the GUI and then I’m instantiating a JTextArea for no reason; and even worse, I have to system.out everything to see the process.
Question: how can I log all the ‘processed data’ to the JTextArea (or sometime JTextPane) without using the Swing components in the thread?
Thanks!
Instead of passing a
JTextArea, pass anOutputStream(e.g. aPrintStream) as parameter. This provides enough flexibility:JTextArea, you pass an outputstream which will append the output to aJTextArea. The writing to the text area should happen on the EDT, but the outputstream takes care of this. Your thread is unaware of thisSystem.out, you just pass theSystem.outdirectly as a parameter