我有一个类(如下所示),扩展了JPanel并包含一个JTextPane.我想将System.out和System.err重定向到我的JTextPane.我的班级似乎没有工作.当我运行它,它会重定向系统打印,但它们不打印到我的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)); } 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,b.length); } }; System.setOut(new PrintStream(out,true)); System.setErr(new PrintStream(out,true)); } }
解决方法
流水流总是混淆我,这就是为什么我的Message Console解决方案不使用它们.无论如何,这里是我尝试使用管道流的控制台.几个差异:
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,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(); } }