Cómo establecer la secuencia de salida en TextArea

Intento crear un panel de GUI para un progtwig y me gustaría que todo, que normalmente se imprima en el símbolo del sistema, se imprima en un objeto TextArea. Tengo el panel de la GUI formateado en su mayor parte, pero no puedo obtener el texto para imprimir en TextArea, aquí está mi archivo:

package guipanel; import javax.swing.*; import java.awt.*; import java.io.*; /** * * @author Dan */ public class GUIPanel extends JFrame { public GUIPanel() { initComponents(); } private void setOutputStream(boolean catchErrors) { System.setOut(aPrintStream); setVisible(true); requestFocus(); if (catchErrors) { System.setErr(aPrintStream); } } private void addTabs(JTabbedPane jTabbedPane1) { JPanel jPanel1 = new JPanel(); JPanel jPanel2 = new JPanel(); JPanel jPanel3 = new JPanel(); JPanel jPanel4 = new JPanel(); jTabbedPane1.add("Main", textArea1); jTabbedPane1.add("Commands", jPanel); jTabbedPane1.add("Rules", jPanel1); jTabbedPane1.add("Links", jPanel2); jTabbedPane1.add("Information", jPanel3); jTabbedPane1.add("Shutdown", jPanel4); setOutputStream(true); } @SuppressWarnings("unchecked") private void initComponents() { textArea1 = new java.awt.TextArea(); jTabbedPane1 = new javax.swing.JTabbedPane(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); jMenu2 = new javax.swing.JMenu(); textArea1.setPreferredSize(new java.awt.Dimension(432, 343)); textArea1.getAccessibleContext().setAccessibleParent(jTabbedPane1); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Evolution-X 639"); setBounds(new java.awt.Rectangle(0, 0, 400, 450)); setResizable(false); getContentPane().setLayout(new java.awt.FlowLayout()); addTabs(jTabbedPane1); getContentPane().add(jTabbedPane1); jMenu1.setText("File"); jMenuBar1.add(jMenu1); jMenu2.setText("Edit"); jMenuBar1.add(jMenu2); setJMenuBar(jMenuBar1); pack(); } public static void main(String args[]) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new GUIPanel().setVisible(true); } }); } private JMenu jMenu1; private JMenu jMenu2; private JMenuBar jMenuBar1; private JTabbedPane jTabbedPane1; private TextArea textArea1; private JPanel jPanel = new JPanel(); private PrintStream aPrintStream = new PrintStream( new FilterOutputStream( new ByteArrayOutputStream())); } 

Necesita redirigir la secuencia de impresión a una secuencia de salida que puede controlar …

Este es un ejemplo de concepto que desarrollé para una aplicación en la que estoy trabajando. Usamos esto para mostrar la consola de salida cuando se está ejecutando en los sitios de los usuarios para que podamos ver lo que se envía a la salida estándar … hasta que arreglemos nuestro registro;

Básicamente, coloca un OutputStream personalizado entre la secuencia de impresión y la consola para capturar la salida, pero aún permite que el contenido se imprima en la consola. Esto es útil si está ejecutando el progtwig desde la línea de comando o IDE. Podría poner un interruptor para detener esto si quisiera …

enter image description here

 public class TestRedirect { public static void main(String[] args) { new TestRedirect(); } public TestRedirect() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } CapturePane capturePane = new CapturePane(); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(capturePane); frame.setSize(200, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); PrintStream ps = System.out; System.setOut(new PrintStream(new StreamCapturer("STDOUT", capturePane, ps))); System.out.println("Hello, this is a test"); System.out.println("Wave if you can see me"); } }); } public class CapturePane extends JPanel implements Consumer { private JTextArea output; public CapturePane() { setLayout(new BorderLayout()); output = new JTextArea(); add(new JScrollPane(output)); } @Override public void appendText(final String text) { if (EventQueue.isDispatchThread()) { output.append(text); output.setCaretPosition(output.getText().length()); } else { EventQueue.invokeLater(new Runnable() { @Override public void run() { appendText(text); } }); } } } public interface Consumer { public void appendText(String text); } public class StreamCapturer extends OutputStream { private StringBuilder buffer; private String prefix; private Consumer consumer; private PrintStream old; public StreamCapturer(String prefix, Consumer consumer, PrintStream old) { this.prefix = prefix; buffer = new StringBuilder(128); buffer.append("[").append(prefix).append("] "); this.old = old; this.consumer = consumer; } @Override public void write(int b) throws IOException { char c = (char) b; String value = Character.toString(c); buffer.append(value); if (value.equals("\n")) { consumer.appendText(buffer.toString()); buffer.delete(0, buffer.length()); buffer.append("[").append(prefix).append("] "); } old.print(c); } } } 

enter image description hereenter image description here

Actualizado con un ejemplo de trabajo. Prueba en Windows 7, Java 6 y Mac OS Lion Java 7

La solución de MadProgrammer es realmente genial, y yo basé la mía en la suya. Sin embargo, como lo señala Loopkin, no trata con caracteres especiales (para ser preciso, falla en todos los caracteres que no son ASCII).

La solución de Loopkin no funcionó para mí, pero finalmente se me ocurrieron dos soluciones que hicieron el trabajo.

Solución 1: maneja cada carácter de 1 byte (hasta U + 00FF)

Esta solución simple maneja cada carácter hasta U + 00FF (cada carácter de 1 byte). Todo es idéntico a MadProgrammer, excepto write() que se define como:

 @Override public void write(int b) throws IOException { buffer.append(Character.toChars((b + 256) % 256)); if ((char) b == '\n') { textArea.append(str); textArea.setCaretPosition(textArea.getDocument().getLength()); buffer.delete(0, buffer.length()); } old.write(b); } 

No puse el prefijo, porque no lo necesitaba.

Solución 2: maneja cada Objeto como salida estándar

Al final, decidí incluir todos los personajes, así que terminé extendiendo directamente PrintStream , y también PrintStream el prefijo / guión. El problema es que no pude anular el método privado de write(String s) , así que anulé todos los métodos de print() :

 public class PrintStreamCapturer extends PrintStream { private JTextArea text; private boolean atLineStart; private String indent; public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream, String indent) { super(capturedStream); this.text = textArea; this.indent = indent; this.atLineStart = true; } public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream) { this(textArea, capturedStream, ""); } private void writeToTextArea(String str) { if (text != null) { synchronized (text) { text.setCaretPosition(text.getDocument().getLength()); text.append(str); } } } private void write(String str) { String[] s = str.split("\n", -1); if (s.length == 0) return; for (int i = 0; i < s.length - 1; i++) { writeWithPotentialIndent(s[i]); writeWithPotentialIndent("\n"); atLineStart = true; } String last = s[s.length - 1]; if (!last.equals("")) { writeWithPotentialIndent(last); } } private void writeWithPotentialIndent(String s) { if (atLineStart) { writeToTextArea(indent + s); atLineStart = false; } else { writeToTextArea(s); } } private void newLine() { write("\n"); } @Override public void print(boolean b) { synchronized (this) { super.print(b); write(String.valueOf(b)); } } @Override public void print(char c) { synchronized (this) { super.print(c); write(String.valueOf(c)); } } @Override public void print(char[] s) { synchronized (this) { super.print(s); write(String.valueOf(s)); } } @Override public void print(double d) { synchronized (this) { super.print(d); write(String.valueOf(d)); } } @Override public void print(float f) { synchronized (this) { super.print(f); write(String.valueOf(f)); } } @Override public void print(int i) { synchronized (this) { super.print(i); write(String.valueOf(i)); } } @Override public void print(long l) { synchronized (this) { super.print(l); write(String.valueOf(l)); } } @Override public void print(Object o) { synchronized (this) { super.print(o); write(String.valueOf(o)); } } @Override public void print(String s) { synchronized (this) { super.print(s); if (s == null) { write("null"); } else { write(s); } } } @Override public void println() { synchronized (this) { newLine(); super.println(); } } @Override public void println(boolean x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(char x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(int x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(long x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(float x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(double x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(char x[]) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(String x) { synchronized (this) { print(x); newLine(); super.println(); } } @Override public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); super.println(); } } } 

Eliminé el aspecto del Consumer para mantenerlo simple, pero todo lo que realmente se necesita está aquí. Así es como utilicé esta clase:

 System.setOut(new PrintStreamCapturer(logTextArea, System.out)); System.setErr(new PrintStreamCapturer(logTextArea, System.err, "[ERROR] ")); 

Me gusta la respuesta de MadProgrammer, pero no creo que esto funcione para los caracteres UTF-8.

En cambio, haría que StreamCapturer amplíe ByteArrayOutputStream y lo use como la implementación de escritura.

  @Override public void write(int b){ if ('\n' == (char) b) { consumer.appendText(toString()); reset(); } else { super.write(b); } old.write(b); } 

Me estoy saltando la parte del prefijo porque no la necesito en mi implementación. Gracias por el código, ¡ha sido de gran ayuda!

Solo una actualización del código original de MadProgrammer para NOOBS: pasar un parámetro JTextArea al constructor, por ejemplo

 new RedirectText(Main.window.textArea1);