将System.out重定向到JTextPane

我有一个类(如下所示)扩展JPanel并包含一个JTextPane 。 我想将System.outSystem.err重定向到我的JTextPane 。 我的class级似乎没有用。 当我运行它时,它会重定向系统打印,但它们不会打印到我的JTextPane 。 请帮忙!

注意:仅在应用程序启动时重定向调用。 但是在启动后的任何时候, System.out调用都不会重定向到JTextPane 。 (例如,如果我在类中放置一个System.out.prinln();它将被调用,但是如果它被放在一个actionListener供以后使用,它就不会重定向)。

 public class OSXConsole extends JPanel { public static final long serialVersionUID = 21362469L; private JTextPane textPane; private PipedOutputStream pipeOut; private PipedInputStream pipeIn; public OSXConsole() { super(new BorderLayout()); textPane = new JTextPane(); this.add(textPane, BorderLayout.CENTER); redirectSystemStreams(); textPane.setBackground(Color.GRAY); textPane.setBorder(new EmptyBorder(5, 5, 5, 5)); } private void updateTextPane(final String text) { SwingUtilities.invokeLater(new Runnable() { public void run() { Document doc = textPane.getDocument(); try { doc.insertString(doc.getLength(), text, null); } catch (BadLocationException e) { throw new RuntimeException(e); } textPane.setCaretPosition(doc.getLength() - 1); } }); } private void redirectSystemStreams() { OutputStream out = new OutputStream() { @Override public void write(final int b) throws IOException { updateTextPane(String.valueOf((char) b)); } @Override public void write(byte[] b, int off, int len) throws IOException { updateTextPane(new String(b, off, len)); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } }; System.setOut(new PrintStream(out, true)); System.setErr(new PrintStream(out, true)); } } 

管道流总是让我困惑,这就是我的消息控制台解决方案不使用它们的原因。 无论如何,这是我尝试使用管道流的控制台。 有几点不同:

a)它使用JTextArea,因为JTextArea比JTextPane更有效,只显示文本。 当然,如果您打算向文本添加属性,则需要一个文本窗格。

b)此解决方案使用线程。 我确定我在某处读到这是防止输出阻塞所必需的。 无论如何,它适用于我的简单测试用例。

 import java.io.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; public class Console implements Runnable { JTextArea displayPane; BufferedReader reader; private Console(JTextArea displayPane, PipedOutputStream pos) { this.displayPane = displayPane; try { PipedInputStream pis = new PipedInputStream( pos ); reader = new BufferedReader( new InputStreamReader(pis) ); } catch(IOException e) {} } public void run() { String line = null; try { while ((line = reader.readLine()) != null) { // displayPane.replaceSelection( line + "\n" ); displayPane.append( line + "\n" ); displayPane.setCaretPosition( displayPane.getDocument().getLength() ); } System.err.println("im here"); } catch (IOException ioe) { JOptionPane.showMessageDialog(null, "Error redirecting output : "+ioe.getMessage()); } } public static void redirectOutput(JTextArea displayPane) { Console.redirectOut(displayPane); Console.redirectErr(displayPane); } public static void redirectOut(JTextArea displayPane) { PipedOutputStream pos = new PipedOutputStream(); System.setOut( new PrintStream(pos, true) ); Console console = new Console(displayPane, pos); new Thread(console).start(); } public static void redirectErr(JTextArea displayPane) { PipedOutputStream pos = new PipedOutputStream(); System.setErr( new PrintStream(pos, true) ); Console console = new Console(displayPane, pos); new Thread(console).start(); } public static void main(String[] args) { JTextArea textArea = new JTextArea(); JScrollPane scrollPane = new JScrollPane( textArea ); JFrame frame = new JFrame("Redirect Output"); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.getContentPane().add( scrollPane ); frame.setSize(200, 100); frame.setVisible(true); Console.redirectOutput( textArea ); final int i = 0; Timer timer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println( new java.util.Date().toString() ); System.err.println( System.currentTimeMillis() ); } }); timer.start(); } } 

Message Console类为您完成此操作。

编辑:

这是一个简单的测试类:

 import java.io.*; import java.awt.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; public class MessageConsoleTest { public static int counter; public static void main(String[] args) throws Exception { JTextComponent textComponent = new JTextPane(); JScrollPane scrollPane = new JScrollPane( textComponent ); JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame = new JFrame("Message Console"); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.getContentPane().add( scrollPane ); frame.setSize(400, 120); frame.setVisible(true); MessageConsole console = new MessageConsole(textComponent); console.redirectOut(); console.redirectErr(Color.RED, null); Timer timer = new Timer(1000, new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { System.out.println( new java.util.Date().toString() ); } }); timer.start(); Thread.sleep(750); Timer timer2 = new Timer(1000, new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { System.err.println( "Error Message: " + ++counter); } }); timer2.start(); } }