SAbbasizadeh
SAbbasizadeh

Reputation: 730

show data on a JTextArea instead of console

I want to have a JTextArea that can completely work instead of a console but I don't know how to do this!

Thank you

Upvotes: 1

Views: 9655

Answers (2)

dacwe
dacwe

Reputation: 43504

The solution to the problem is to redirect System.{in,out,err} to a JTextArea.


  • Starting with System.out it's pretty straight forward to to redirect it to your JTextArea component using System.setOut method. In the example below I've done this using pipes and SwingWorker but that is all fancy stuff to actually get the output simpler to the swing component.

  • Emulating System.in is simular, you need to redirect your keystrokes to the the System.in using System.setIn. Again, in the example below, I've used pipes to get a nicer interface. I also buffer the line (just like a "normal" console would do) till you hit enter. (Note that for example arrow keys will not work but it shouldn't be to much work to get it also to be handled/ignored.)


The text in the screenshot below was produced by a number of calls to the "normal" System.out.print.. method and then waiting for input on System.in using a Scanner:

screenshot

public static JTextArea console(final InputStream out, final PrintWriter in) {
    final JTextArea area = new JTextArea();

    // handle "System.out"
    new SwingWorker<Void, String>() {
        @Override protected Void doInBackground() throws Exception {
            Scanner s = new Scanner(out);
            while (s.hasNextLine()) publish(s.nextLine() + "\n");
            return null;
        }
        @Override protected void process(List<String> chunks) {
            for (String line : chunks) area.append(line);
        }
    }.execute();

    // handle "System.in"
    area.addKeyListener(new KeyAdapter() {
        private StringBuffer line = new StringBuffer();
        @Override public void keyTyped(KeyEvent e) {
            char c = e.getKeyChar();
            if (c == KeyEvent.VK_ENTER) {
                in.println(line);
                line.setLength(0); 
            } else if (c == KeyEvent.VK_BACK_SPACE) { 
                line.setLength(line.length() - 1); 
            } else if (!Character.isISOControl(c)) {
                line.append(e.getKeyChar());
            }
        }
    });

    return area;
}

And the example main method:

public static void main(String[] args) throws IOException {

    // 1. create the pipes
    PipedInputStream inPipe = new PipedInputStream();
    PipedInputStream outPipe = new PipedInputStream();

    // 2. set the System.in and System.out streams
    System.setIn(inPipe);
    System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));

    PrintWriter inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);

    // 3. create the gui 
    JFrame frame = new JFrame("\"Console\"");
    frame.add(console(outPipe, inWriter));
    frame.setSize(400, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    // 4. write some output (to JTextArea)
    System.out.println("Hello World!");
    System.out.println("Test");
    System.out.println("Test");
    System.out.println("Test");

    // 5. get some input (from JTextArea)
    Scanner s = new Scanner(System.in);
    System.out.printf("got from input: \"%s\"%n", s.nextLine());
}

Upvotes: 18

Boris Pavlović
Boris Pavlović

Reputation: 64622

Take a look at the Simple Java Console (Swing based)

Upvotes: 1

Related Questions