Я хочу иметь полностью работающую JTextArea вместо консоли, но я не знаю, как это сделать!
Спасибо
Я хочу иметь полностью работающую JTextArea вместо консоли, но я не знаю, как это сделать!
Спасибо
Решение проблемы — перенаправить System.{in,out,err}
на JTextArea
.
Начиная с System.out
довольно просто перенаправить его на ваш компонент JTextArea
с помощью System.setOut
. В приведенном ниже примере я сделал это, используя каналы и SwingWorker
, но это все причудливые вещи, чтобы на самом деле упростить вывод для компонента свинга.
Эмуляция System.in
аналогична, вам нужно перенаправить нажатия клавиш на System.in
с помощью System.setIn
. Опять же, в приведенном ниже примере я использовал конвейеры, чтобы получить более приятный интерфейс. Я также буферизую строку (точно так же, как это делает «обычная» консоль), пока вы не нажмете Enter. (Обратите внимание, что, например, клавиши со стрелками не будут работать, но не должно быть слишком много усилий, чтобы заставить их также обрабатываться/игнорироваться.)
Текст на снимке экрана ниже был создан несколькими вызовами «нормального» метода System.out.print..
, а затем ожиданием ввода в System.in
с использованием Scanner
:
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;
}
И пример метода main
:
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());
}
Взгляните на Простую консоль Java (на основе Swing)