Здесь ответы на 2 вопроса:
- Как перенаправить стандартный вывод System.out в данном случае в текстовое поле JTextArea?
- Как обеспечить правильное отображение русских букв при перенаправлении вывода?
Если мы хотим организовать перенаправление в текстовое поле, значит мы создаём оконное приложение, и значит главный класс нашей программы расширяет класс JFrame.
За перенаправление вывода информационных сообщений и ошибок отвечают два метода класса System:
System.setOut(printStream);
System.setErr(printStream);
Двум этим методам нужно указать некий экземпляр printStream, этим мы и воспользуемся и создадим свой класс CustomOutputStream, в котором переопределим пару методов:
public void write(byte[] buffer, int offset, int length) throws IOException
public void write(int b) throws IOException
чтобы сообщить java, куда нужно передавать байты.
Переопределение первого из этих двух методов важно для правильного вывода русских букв. Поскольку символ в java состоит из двух байт, если мы начнём только с помощью второго метода выводить приходящие русские символы побайтово, а не посимвольно, мы получим белеберду.
import java.awt.BorderLayout;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class MainWindow extends JFrame {
private static final long serialVersionUID = -205695062747265013L;
public static void main(String[] args) {
// Создаём окно, панель в нём и текстовое поле для логирования
MainWindow mainWindow = new MainWindow();
JTextArea logTextArea = new JTextArea();
JPanel jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
mainWindow.setContentPane(jContentPane);
jContentPane.add(logTextArea, BorderLayout.CENTER);
mainWindow.setSize(800, 550);
mainWindow.setVisible(true);
// Перенаправляем стандартный вывод в текстовое поле
PrintStream printStream = new PrintStream(new CustomOutputStream(
logTextArea));
System.setOut(printStream);
System.setErr(printStream);
System.out.println("Hi from JTextAea!");
}
}
/**
* This class extends from OutputStream to redirect output to a JTextArrea
*
*/
class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
// @Override
// как не надо делать
// public void write(int b) throws IOException {
// // redirects data to the text area
// textArea.append(String.valueOf((char) b));
// // scrolls the text area to the end of data
// textArea.setCaretPosition(textArea.getDocument().getLength());
// }
// правильная русская кодировка
@Override
public void write(byte[] buffer, int offset, int length) throws IOException {
final String text = new String(buffer, offset, length);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textArea.append (text);
}
});
}
@Override
public void write(int b) throws IOException {
write(new byte[] { (byte) b }, 0, 1);
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class MainWindow extends JFrame {
private static final long serialVersionUID = -205695062747265013L;
public static void main(String[] args) {
// Создаём окно, панель в нём и текстовое поле для логирования
MainWindow mainWindow = new MainWindow();
JTextArea logTextArea = new JTextArea();
JPanel jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
mainWindow.setContentPane(jContentPane);
jContentPane.add(logTextArea, BorderLayout.CENTER);
mainWindow.setSize(800, 550);
mainWindow.setVisible(true);
// Перенаправляем стандартный вывод в текстовое поле
PrintStream printStream = new PrintStream(new CustomOutputStream(
logTextArea));
System.setOut(printStream);
System.setErr(printStream);
System.out.println("Hi from JTextAea!");
}
}
/**
* This class extends from OutputStream to redirect output to a JTextArrea
*
*/
class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
// @Override
// как не надо делать
// public void write(int b) throws IOException {
// // redirects data to the text area
// textArea.append(String.valueOf((char) b));
// // scrolls the text area to the end of data
// textArea.setCaretPosition(textArea.getDocument().getLength());
// }
// правильная русская кодировка
@Override
public void write(byte[] buffer, int offset, int length) throws IOException {
final String text = new String(buffer, offset, length);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textArea.append (text);
}
});
}
@Override
public void write(int b) throws IOException {
write(new byte[] { (byte) b }, 0, 1);
}
}
