show data on a JTextArea instead of console

2019-01-14 05:15发布

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

2条回答
太酷不给撩
2楼-- · 2019-01-14 05:32
爷、活的狠高调
3楼-- · 2019-01-14 05:49

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());
}
查看更多
登录 后发表回答