Re: How do you _really_ get a PrintStream to flush all the time?



Ok, I just figured out a piece of the problem. The console is created with
a reader thread. Additionally, each time something comes into the buffer, a
new thread is created to append it to the JTextArea. Races between these
threads are causing the problem.

If I remark out the subthread creation:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
and the appropriate corresponding closing brackets, behavior improves
greatly.

However, then I run the danger of overrunning the buffer (and maybe other
problems).

I suspect that some clever use of synchronize is the proper cure for my
problem. I'm not sure whether to synchronize on the JTextArea or on the
PrintStream, or what....

Thanks,

Rob


> I create my own PrintStream directed to a JTextArea to act as a console
for
> a Swing application. I found an example of doing this online &
implemented
> away...
>
> Unfortunately, writing to the console isn't at all deterministic.
Messages
> get trimmed. They are printed out of order, linefeeds don't happen.
> Generally, it is a mess. And no end of flush() does any good at all...
>
> Any suggestions are appreciated,
>
> Rob
>
> public class Console extends JPanel {
> static PrintStream out;
> private PipedInputStream piOut;
> private PipedOutputStream poOut;
> private JTextArea textArea = new JTextArea();
>
> public Console() throws IOException {
> piOut = new PipedInputStream();
> poOut = new PipedOutputStream(piOut);
> out = new PrintStream(poOut, true);
> textArea.setEditable(false);
> textArea.setRows(10);
> textArea.setColumns(80);
> add(new JScrollPane(textArea), BorderLayout.CENTER);
> setVisible(true);
> new ReaderThread(piOut).start();
> }
>
> class ReaderThread extends Thread {
> PipedInputStream pi;
> ReaderThread(PipedInputStream pi) {
> this.pi = pi;
> }
> public void run() {
> final byte[] buf = new byte[1024];
> try {
> while (true) {
> final int len = pi.read(buf);
> if (len == -1) {
> break;
> }
> SwingUtilities.invokeLater(new Runnable() {
> public void run() {
> textArea.append(new String(buf, 0, len));
> // Make sure the last line is always visible
> textArea.setCaretPosition(textArea.getDocument().getLength());
> // Keep the text area down to a certain character size
> int idealSize = 10000;
> int maxExcess = 5000;
> int excess = textArea.getDocument().getLength() - idealSize;
> if (excess >= maxExcess) {
> textArea.replaceRange("", 0, excess);
> }
> }
> });
> }
> } catch (IOException e) {
> }
> }
> }
> }
>
>


.



Relevant Pages