java – 将System.out重定向到JTextPane

前端之家收集整理的这篇文章主要介绍了java – 将System.out重定向到JTextPane前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个类(如下所示),扩展了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();
    }
}

猜你在找的Java相关文章