4

Client has gui and extra thread (to process socket input and print it out to passes object of type PrintStream). The gui form has new javax.swing.JTextArea(). I need to pass to thread the object PrintStream to write to: ClientThreadIn(PrintStream inOutput){...}. How to create/bind gui JTextArea to accept data form ClientThreadIn using PrintStream?


Client:

    in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
    out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
ClientThreadIn threadIn = new ClientThreadIn(in, System.out); // client passes it's System.out to thread for writing

So JTextArea should be similar to console. It should be able to accept data from Thread (actually Thread writes to PrintStream of gui)... Is there something similar to JTextArea.getInputStream()?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
J.Olufsen
  • 13,415
  • 44
  • 120
  • 185

1 Answers1

10

One way is to create a class that links the JTextArea to an OutputStream, say called TextAreaOutputStream, and have it extend OutputStream. Give it a StringBuilder object to hold the String that it is constructing in the write(int b) override, and give it a reference to the JTextArea that you want to write text to. Then when a new line character is encountered, write the String to the JTextArea, but be sure to do this on the Swing event thread or EDT.

For example:

import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TextAreaOutputStream extends OutputStream {

   private final JTextArea textArea;
   private final StringBuilder sb = new StringBuilder();
   private String title;

   public TextAreaOutputStream(final JTextArea textArea, String title) {
      this.textArea = textArea;
      this.title = title;
      sb.append(title + "> ");
   }

   @Override
   public void flush() {
   }

   @Override
   public void close() {
   }

   @Override
   public void write(int b) throws IOException {

      if (b == '\r')
         return;

      if (b == '\n') {
         final String text = sb.toString() + "\n";
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               textArea.append(text);
            }
         });
         sb.setLength(0);
         sb.append(title + "> ");

         return;
      }

      sb.append((char) b);
   }
}

Then it is trivial to wrap this in a PrintStream object and have it used by your socket.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    @RCola: That's not necessary. This is just code that I have used in one of my program where I had a JTextArea that was receiving Strings from several Sockets, and I had to indicate in the JTextArea the source of the String. For instance, I had both an output stream and an error stream to display. – Hovercraft Full Of Eels Jun 03 '12 at 19:45