I've got a JFrame that contains a single JPanel that contains a single JTextArea. I've successfully managed to point System.out to the JTextArea, but when I try to use Scanner(System.in) to parse input from the JTextArea, it doesn't even seem to load anything. As in, when I build and run the application, nothing happens, no frame is presented. Here is my code:
/**
* Create the frame.
*/
public TerminalForm() {
setTitle("Terminal");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(100, 100, 570, 370);
contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder());
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
PipedInputStream inPipe = new PipedInputStream();
PipedInputStream outPipe = new PipedInputStream();
System.setIn(inPipe);
try {
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
} catch (IOException e1) {
e1.printStackTrace();
}
PrintWriter inWriter = null;
try {
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
} catch (IOException e) {
e.printStackTrace();
}
final JTextArea txtIO = console(outPipe, inWriter);
txtIO.setFont(new Font("Andale Mono", Font.PLAIN, 12));
txtIO.setCaretColor(new Color(50, 205, 50));
txtIO.getCaret().setVisible(true);
txtIO.getCaret().setSelectionVisible(true);
txtIO.setLineWrap(true);
txtIO.setForeground(new Color(50, 205, 50));
txtIO.setBackground(new Color(0, 0, 0));
txtIO.setBorder(BorderFactory.createEmptyBorder());
contentPane.add(txtIO);
// 5. get some input (from JTextArea)
Scanner s = new Scanner(System.in);
System.out.printf("got from input: \"%s\"%n", s.nextLine());
}
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");
s.close();
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;
}
you didn't set the frame visible.
If this were my code, I'd not have the user type directly into the JTextArea, but rather in a JTextField that is directly below the JTextArea (BorderLayout.SOUTH to the JTextArea which is held in a JScrollPane that is BorderLayout.CENTER). I'd then accept input via enter, via an ActionListener, and then print what the user enters into the JTextArea with some indication that it's from the user, and also send the entered text out via the OutputStream, or better a PrintStream.
For example, something like,