Redirecting System.out to JTextPane

后端 未结 3 1867
小鲜肉
小鲜肉 2020-11-28 14:39

I have a class (shown below) that extends JPanel and contains a JTextPane. I want to redirect System.out and System.err t

相关标签:
3条回答
  • 2020-11-28 15:08

    Piped streams always confuse me, which is why my Message Console solution doesn't use them. Anyway here is my attempt at a console using piped streams. A couple of differences:

    a) it uses a JTextArea because a JTextArea is more efficient than a JTextPane for just displaying text. Of course if you intend to add attributes to the text then you need a text pane.

    b) this solution uses Threads. I'm sure I read somewhere that this was necessary to prevent blocking of the output. Anyway it works in my simple test case.

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-28 15:24

    In the following link you can find the MessageConsole class that someone mentioned. I implemented a software and used this solution and it works perfect for me. I used the Netbeans design tool, so the code regarding the visual appearance of the JTextPane is a bit cumbersome, so I'm not going to place it here.

    
    JTextPane jTextPane = new JTextPane();
    
    MessageConsole console = new MessageConsole(jTextPane);
    /*
    This parameters are optional, but if you are looking for a solution with JTextPane it is because you need them, at least color.
    */
    console.redirectErr(Color.RED, null);
    console.redirectOut();
    
    //some event
    private void jButton1ActionPerformed(ActionEvent evt) {
        /*
        In this event I execute a function of my business.
        I put it in a thread so that it does not block the graphical interface.
        There are many calls to System.out.println() and System.err.println()
        */
        BusinessClass bc = new BusinessClass();
        Runnable runnable = () -> {
            bc.someBusinessFn();
        };
        thread = new Thread(runnable);
        thread.start();
    }
    
    //My main method
    public static void main(String args[]) {
            /* Create and display the GUI */
            EventQueue.invokeLater(() -> {
                new MyJFrame().setVisible(true);
            });
    }
    

    Edit

    Sorry, I did not realize that in the response similar to this, they had put the link to the MessageConsole class. I didn't see it and I also wanted to show my solution.

    0 讨论(0)
  • 2020-11-28 15:25

    Message Console class does this for you.

    Edit:

    Here is a simple test class:

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题