当前位置: 首页 > 面试题库 >

将System.out重定向到JTextPane

杨景山
2023-03-14
问题内容

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

注意:
仅在应用程序启动时才重定向呼叫。但是,启动后的任何时间System.out都不会将呼叫重定向到JTextPane。(即,如果我将a放置System.out.prinln();在类中,它将被调用,但是如果将其放置在a中以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));
    }


}

问题答案:

管道流总是使我感到困惑,这就是为什么我的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, 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();
    }
}


 类似资料:
  • 问题内容: 我需要将System.out / err.println输出重定向到slf4j。 我知道这不是正确记录日志的方法, 但是有一个外部库记录到System.out 问题答案: 您可以使用sysout-over-slf4j。 sysout-over- slf4j模块允许用户将对System.out和System.err的所有调用重定向到SLF4J定义的记录器,该记录器的名称是在其中进行Sys

  • 我想在日志文件中看到我的jnlp标准输出。请建议。p. s.我jnlp在windows下运行,使用log4j记录器

  • 问题内容: 我在cyberciti.biz的评论中看到了这个有趣的问题。 我发现我什至找不到在sh的单行命令中执行此操作的灵活方法。 到目前为止,我对解决方案的想法是: 但是您会看到,这不是同步的,而且致命的是,它是如此丑陋。 欢迎与您分享这个想法。:) 问题答案: 你要 这里的顺序很重要。假设stdin(fd 0),stdout(fd 1)和stderr(fd 2)最初都连接到tty,因此 首先

  • 问题内容: 我想使用PHP将所有www.domain.com请求重定向到domain.com,基本上是: 但是我确实想像SO中那样维护请求的URL,例如: 应该重定向到: 我不想依靠解决方案,并且我不确定要使用哪种变体来实现这一目标。同样,保留HTTPS协议将是一个加号。 我应该怎么做? 问题答案: 将用户重定向到完全相同的页面,www。完整。 因此,要摆脱www。,我们只需替换一行: 那应该起作

  • 我们使用拉维5。要将http连接重定向到https,请使用中间件HttpsProtocol。 在我们的4个测试用例中,只有1个正确工作(最后一个重定向)。其他3种情况的中间件添加了url extra index.php。 http://www.aqualink.az/index.php ---

  • 我想问一下HTTP到HTTPS的重定向。正如我们所知,重定向是通过从web服务器端重定向来实现的。但是,当涉及到https重定向时,它可以通过两种方式完成,服务器端()和应用程序端()。我想知道: 以下哪种方法有效且性能更好。 考虑到同一服务器上的多个域和域,每种方法的优缺点 非常感谢。 参考: 将Laravel中的WWW重定向到非WWW-堆栈溢出