Tarek
Tarek

Reputation: 65

How to redirect javax.mail.Session setDebug to jTextArea

How can I redirect javax.mail.Session setDebug to jTextArea ?

ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
Session mailSession = Session.getDefaultInstance(props, null);
logger.info("JAVAMAIL debug mode is ON");
mailSession.setDebug(true);
mailSession.setDebugOut(ps);
logger.info(os);

Upvotes: 2

Views: 688

Answers (2)

Freek de Bruijn
Freek de Bruijn

Reputation: 3622

You could use the nice CustomOutputStream class described on http://www.codejava.net/java-se/swing/redirect-standard-output-streams-to-jtextarea:

import java.io.*;
import java.util.Properties;
import javax.mail.Session;
import javax.swing.*;

public class PrintStream2TextArea {
    public static void main(final String[] arguments) {
        new PrintStream2TextArea().launchGui();
    }

    private void launchGui() {
        final JFrame frame = new JFrame("Stack Overflow");
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        final JTextArea textArea = new JTextArea(42, 28);
        setupMailSession(new Properties(), textArea);
        frame.getContentPane().add(textArea);
        frame.setVisible(true);
    }

    private void setupMailSession(final Properties props, final JTextArea textArea) {
        PrintStream ps = new PrintStream(new CustomOutputStream(textArea));
        Session mailSession = Session.getDefaultInstance(props, null);
        //logger.info("JAVAMAIL debug mode is ON");
        mailSession.setDebug(true);
        mailSession.setDebugOut(ps);
        //logger.info(os);
    }

    /**
     * This class extends from OutputStream to redirect output to a JTextArea.
     *
     * @author www.codejava.net
     */
    public static class CustomOutputStream extends OutputStream {
        private JTextArea textArea;

        public CustomOutputStream(JTextArea textArea) {
            this.textArea = textArea;
        }

        @Override
        public void write(int b) throws IOException {
            // redirects data to the text area
            textArea.append(String.valueOf((char)b));
            // scrolls the text area to the end of data
            textArea.setCaretPosition(textArea.getDocument().getLength());
        }
    }
}

Upvotes: 1

jmehrens
jmehrens

Reputation: 11045

  1. You can create or find a swing hander implementation and attach it to the javax.mail logger namespace used by JavaMail.
  2. You can use threads and piped I/O to read the debug output and write it to the textarea.
  3. You can create an buffered output stream that writes to the textarea during an 'autoflush'.

    public class AreaDebug {
    
        public static void main(String[] args) throws Exception {
            EventQueue.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    test();
                }
            });
        }
    
        private static void test() {
            assert EventQueue.isDispatchThread() : Thread.currentThread();
            final Session s = Session.getInstance(new Properties());
            JTextArea area = new JTextArea();
            Adaptor out = new Adaptor(area.getDocument());
            s.setDebugOut(new PrintStream(out, true)); //Default encoding?
            s.setDebug(true);
            System.out.println(area.getText());
        }
    
        private static class Adaptor extends ByteArrayOutputStream {
    
            private final Document d;
    
            Adaptor(final Document d) {
                this.d = d;
            }
    
            @Override
            public void flush() throws IOException {
                final String a;
                synchronized (this) {
                    super.flush();
                    a = super.toString(); //Default encoding?
                    super.reset();
                }
    
                Updater u = new Updater(d, a);
                if (EventQueue.isDispatchThread()) {
                    u.run();
                } else {
                    try {
                        EventQueue.invokeAndWait(u);
                    } catch (InterruptedException ex) {
                        Thread.currentThread().interrupt();
                        throw new InterruptedIOException();
                    } catch (InvocationTargetException ex) {
                        throw new IOException(ex);
                    }
                }
            }
        }
    
        private static class Updater implements Runnable {
    
            private final Document d;
            private final String append;
    
            Updater(Document d, String append) {
                this.d = d;
                this.append = append;
            }
    
            @Override
            public void run() {
                try {
                    d.insertString(d.getLength(), append, (AttributeSet) null);
                } catch (BadLocationException ex) {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        }
    }
    

Upvotes: 1

Related Questions