Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes

SendMailApp Class Reference

Simple SMTP send mail application that demonstrates usage of the MailTransport class. More...

Inheritance diagram for SendMailApp:
Inheritance graph
[legend]
Collaboration diagram for SendMailApp:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SendMailApp ()
 Creates an instance of the send mail application GUI.
void clearLog ()
 Clears the log.
void println (String str)
 Logs message terminated with new line.
void onSendCompleted (String errorMessage)
 On send completed call-back.
void actionPerformed (ActionEvent evt)
 Handles events from 'enqueue' and 'send immediately' buttons.

Static Public Member Functions

static void main (String args[])
 Main entry point.

Private Member Functions

void enqueueMessage (boolean sendImmediately)
 Enqueues message and optionally flushes the queue.
void formWindowClosing (WindowEvent evt)
 Closes application gracefully.

Static Private Member Functions

static String now ()
 Gets current time stamp.

Private Attributes

JButton buttonEnqueue
 GUI components.
JButton buttonSend
JLabel labelServer
JTextField fieldServer
JLabel labelFrom
JTextField fieldFrom
JLabel labelTo
JTextField fieldTo
JLabel labelSubject
JTextField fieldSubject
JScrollPane messageScrollPane
JTextArea messageContents
JTabbedPane tabbedPane
JScrollPane logPane
JTextArea logArea
MailTransport mailTransport = null
 Instance of the current mail transport channel.

Static Private Attributes

static final long serialVersionUID = 6679954030573701419L
 Implements java.io.Serializable interface.
static final String appTitle = "IP1-6.1: SMTP Send Mail"
 Common application title prefix.

Detailed Description

Simple SMTP send mail application that demonstrates usage of the MailTransport class.

It also offers presentation context for instances of MailTransport.

Author:
Mikica B Kocic

Definition at line 32 of file SendMailApp.java.


Constructor & Destructor Documentation

SendMailApp.SendMailApp (  )

Creates an instance of the send mail application GUI.

Definition at line 75 of file SendMailApp.java.

References appTitle, buttonEnqueue, buttonSend, fieldFrom, fieldServer, fieldSubject, fieldTo, formWindowClosing(), labelFrom, labelServer, labelSubject, labelTo, logArea, logPane, messageContents, messageScrollPane, and tabbedPane.

Referenced by main().

    {
        super( appTitle + ", idle" );
            
        setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
        
        /////////////////////////////////////////////////////// GUI COMPONENTS ///////////
        
        addWindowListener( new java.awt.event.WindowAdapter () {
            public void windowClosing( java.awt.event.WindowEvent evt ) {
                formWindowClosing( evt );
            }
        });

        Font btnFont  = new Font( Font.SANS_SERIF, Font.BOLD,  12 );
        Font textFont = new Font( Font.SANS_SERIF, Font.PLAIN, 15 );
        Font logFont  = new Font( Font.MONOSPACED, Font.PLAIN, 14 );
        
        buttonEnqueue    = new JButton ();
        buttonSend       = new JButton ();
        labelServer      = new JLabel ();
        fieldServer       = new JTextField ();
        labelFrom        = new JLabel ();
        fieldFrom         = new JTextField ();
        labelTo          = new JLabel ();
        fieldTo           = new JTextField ();
        labelSubject     = new JLabel ();
        fieldSubject      = new JTextField ();

        labelServer.setText( "STMP Server:" );
        labelFrom.setText( "From:" );
        labelTo.setText( "To:" );
        labelSubject.setText( "Subject:" );
        
        fieldServer.setColumns( 40 );
        fieldFrom.setColumns( 40 );
        fieldTo.setColumns( 40 );
        fieldSubject.setColumns( 40 );

        buttonEnqueue.setFont( btnFont );
        buttonSend.setFont( btnFont );
        labelServer.setFont( textFont );
        labelFrom.setFont( textFont );
        labelTo.setFont( textFont );
        labelSubject.setFont( textFont );
        fieldServer.setFont( textFont );
        fieldFrom.setFont( textFont );
        fieldTo.setFont( textFont );
        fieldSubject.setFont( textFont );

        messageContents = new JTextArea ();
        messageContents.setLineWrap( true );
        messageContents.setWrapStyleWord( true );
        messageContents.setEditable( true );
        messageContents.setFont( textFont );

        messageScrollPane = new JScrollPane ();
        messageScrollPane.setViewportView( messageContents );
        
        logArea = new JTextArea ();
        logArea.setLineWrap( true );
        logArea.setWrapStyleWord( true );
        logArea.setEditable( false );
        logArea.setFont( logFont );
        logArea.setBackground( new Color( 255, 255, 240 ) );
        logArea.setForeground( Color.BLACK );
        logArea.setWrapStyleWord( true );
        
        logPane = new JScrollPane ();
        logPane.setViewportView( logArea );

        buttonEnqueue.setText( "Enqueue Message" );
        buttonEnqueue.addActionListener( this );

        buttonSend.setText( "Send Immediatelly" );
        buttonSend.addActionListener( this );

        /////////////////////////////////////////////////////// COMPONENTS LAYOUT ////////

        JPanel sendMailPane = new JPanel (); 
        sendMailPane.setBorder( new MetalBorders.Flush3DBorder() );
        
        GroupLayout layout = new GroupLayout( sendMailPane );
        sendMailPane.setLayout( layout );
        layout.setAutoCreateContainerGaps( true );
        layout.setAutoCreateGaps( true );
        
        layout.setHorizontalGroup
        (
            layout
            .createParallelGroup( GroupLayout.Alignment.LEADING )
            .addGroup
            (
                layout
                .createSequentialGroup ()
                .addGroup
                (
                    layout
                    .createParallelGroup( GroupLayout.Alignment.TRAILING )
                    .addComponent( messageScrollPane )
                    .addGroup
                    (
                        GroupLayout.Alignment.LEADING, 
                        layout
                        .createSequentialGroup ()
                        .addContainerGap( 10, 10 )
                        .addGroup
                        (
                            layout
                            .createParallelGroup( GroupLayout.Alignment.LEADING )
                            .addComponent( labelServer )
                            .addComponent( labelFrom )
                            .addComponent( labelTo )
                            .addComponent( labelSubject )
                        )
                        .addGroup
                        (
                            layout
                            .createParallelGroup( GroupLayout.Alignment.LEADING, false )
                            .addComponent( fieldServer )
                            .addComponent( fieldFrom )
                            .addComponent( fieldTo )
                            .addComponent( fieldSubject )
                        )
                    )
                    .addGroup
                    (
                        GroupLayout.Alignment.LEADING,
                        layout
                        .createSequentialGroup ()
                        .addContainerGap( 10, 10 )
                        .addGroup
                        (
                            layout
                            .createParallelGroup( GroupLayout.Alignment.LEADING, false )
                            .addComponent( buttonEnqueue )
                        )
                        .addGroup
                        (
                            layout
                            .createParallelGroup( GroupLayout.Alignment.LEADING, false )
                            .addComponent( buttonSend )
                        )
                    )
                )
            )
        );
        
        layout.setVerticalGroup
        (
            layout
            .createParallelGroup( GroupLayout.Alignment.LEADING )
            .addGroup
            (
                layout
                .createSequentialGroup ()
                .addGroup
                (
                    layout
                    .createParallelGroup( GroupLayout.Alignment.BASELINE )
                    .addComponent( labelServer )
                    .addComponent( fieldServer )
                )
                .addGroup
                (
                    layout
                    .createParallelGroup( GroupLayout.Alignment.BASELINE )
                    .addComponent( labelFrom )
                    .addComponent( fieldFrom )
                )
                .addGroup
                (
                    layout
                    .createParallelGroup( GroupLayout.Alignment.BASELINE )
                    .addComponent( labelTo )
                    .addComponent( fieldTo )
                )
                .addGroup
                (
                    layout.createParallelGroup( GroupLayout.Alignment.BASELINE )
                    .addComponent( labelSubject )
                    .addComponent( fieldSubject )
                )
                .addGroup
                (
                    layout.createParallelGroup( GroupLayout.Alignment.BASELINE )
                    .addComponent( buttonEnqueue )
                    .addComponent( buttonSend )
                )
                .addComponent( messageScrollPane )
            )
        );

        pack ();

        /////////////////////////////////////////////////////// TABBED PANES /////////////
        
        tabbedPane = new JTabbedPane ();
        getContentPane().add( tabbedPane );
        tabbedPane.addTab( "Compose Message", sendMailPane );
        tabbedPane.addTab( "MTA: Idle", logPane );

        /////////////////////////////////////////////////////// WINDOW PLACEMENT /////////
        
        /* Adjust window dimensions not to exceed screen dimensions ...
         */
        Dimension win = new Dimension( 695, 590 );
        Dimension scsz = Toolkit.getDefaultToolkit().getScreenSize();
        win.width  = Math.min( win.width, scsz.width );
        win.height = Math.min( win.height, scsz.height - 40 );
        setMinimumSize( win );
        setSize( win );
        
        /* ... then center window on the screen.
         */
        setLocation( ( scsz.width - win.width )/2, ( scsz.height - 40 - win.height )/2 );
        
        /* Ready for user to type in...
         */
        fieldServer.requestFocus ();
    }

Member Function Documentation

void SendMailApp.actionPerformed ( ActionEvent  evt )

Handles events from 'enqueue' and 'send immediately' buttons.

Definition at line 500 of file SendMailApp.java.

References buttonSend, and enqueueMessage().

    {
        boolean sendImmediately = ( evt.getSource () == buttonSend );
        
        enqueueMessage( sendImmediately );
    }
void SendMailApp.clearLog (  )

Clears the log.

Definition at line 399 of file SendMailApp.java.

References logArea.

    {
        synchronized( logArea )
        {
            logArea.setText( "" );
            logArea.setRows( 0 );
            logArea.setCaretPosition( logArea.getText().length () );
        }
    }
void SendMailApp.enqueueMessage ( boolean  sendImmediately ) [private]

Enqueues message and optionally flushes the queue.

It creates new instance of the mail transport channel (if there is no any and also keeps GUI elements synchronized with the current state of the mail transport instance.

Definition at line 302 of file SendMailApp.java.

References appTitle, MailTransport.enqueueMessage(), fieldFrom, fieldServer, fieldSubject, fieldTo, MailTransport.getQueueSize(), mailTransport, messageContents, MailTransport.noMoreMessages(), println(), MailTransport.startSending(), and tabbedPane.

Referenced by actionPerformed().

    {
        try 
        {
            /* Create new instance of mail transport (if there is no any) and lock the 
             * server input field so the user cannot change server name 
             * until the queue is flushed (because all subsequent messages
             * will be enqueued in the queue of the currently created MailTransport
             * instance). 
             */
            synchronized( this ) 
            {
                if ( mailTransport == null ) {
                    mailTransport = new MailTransport( this, fieldServer.getText(), 25 );
                    fieldServer.setEnabled( false );
                }
            }

            /* Now, create and put the message into sending queue of the mail transport...
             */
            String   from       = fieldFrom.getText().trim(); 
            String[] recipients = fieldTo.getText().trim().split(",");
            String   subject    = fieldSubject.getText().trim();
            String   contents   = messageContents.getText().trim();
           
            /* Enqueue message only if there is recipient specified
             */
            if ( recipients.length > 0 && ! recipients[0].isEmpty () )
            {
                mailTransport.enqueueMessage( from, recipients, subject, contents );

                int msgCount = mailTransport.getQueueSize ();
                assert msgCount > 0 
                    : "Ouch!. We have enqueued message, but the queue is still empty?";
                if ( msgCount == 1 ) {
                    setTitle( appTitle + ", 1 message waiting to be sent..." );
                } else {
                    setTitle( appTitle + ", " + msgCount 
                            + " messages waiting to be sent..." );
                }
                
                /* Keep "From:" field and clear other variable fields
                 */
                fieldTo.setText( "" );
                fieldSubject.setText( "" );
                messageContents.setText( "" );
            }
            
            /* If user wants to flush the queue, then start the worker thread
             * and indicate that we have no more messages to send, then release
             * mailTransport agent.
             */
            if ( sendImmediately && mailTransport.getQueueSize () > 0 )
            {
                println( "------------------------------------------------------------" );

                tabbedPane.setForegroundAt( 1, Color.BLUE );
                tabbedPane.setTitleAt( 1, "MTA: Sending..." );
                tabbedPane.setSelectedIndex( 1 );
                setTitle( appTitle + ", Sending messages..." );
                
                mailTransport.noMoreMessages ();
                mailTransport.startSending ();
                
                /* Release mailTransport agent and unlock the server field
                 */
                mailTransport = null;
                fieldServer.setEnabled( true );
            }
            else if ( mailTransport.getQueueSize () == 0 )
            {
                tabbedPane.setForegroundAt( 1, Color.BLACK );
                tabbedPane.setTitleAt( 1, "MTA: Idle" );
                setTitle( appTitle + ", idle" );
                
                /* Release mailTransport agent and unlock the server field
                 */
                mailTransport = null;
                fieldServer.setEnabled( true );
            }
            else
            {
                tabbedPane.setForegroundAt( 1, Color.BLACK );
                tabbedPane.setTitleAt( 1, "MTA: Idle" );
            }
        }
        catch( MessagingException e )
        {
            JOptionPane.showMessageDialog( this, 
                    "Failed to put e-mail message into the queue\n" + e.toString (), 
                    "Error while enqueing the message...", JOptionPane.ERROR_MESSAGE );
        }
    }
void SendMailApp.formWindowClosing ( WindowEvent  evt ) [private]

Closes application gracefully.

Parameters:
evt

Definition at line 482 of file SendMailApp.java.

References mailTransport, and MailTransport.noMoreMessages().

Referenced by SendMailApp().

    {
        /* Signal to mail transport's worker thread to flush the queue before exit
         */
        synchronized( this ) 
        {
            if ( mailTransport != null ) {
                mailTransport.noMoreMessages ();
                mailTransport = null;
            }
        }

        System.exit( 0 );
    }
static void SendMailApp.main ( String  args[] ) [static]

Main entry point.

Creates instance of SendMailApp application.

Parameters:
argsthe command line arguments

Definition at line 512 of file SendMailApp.java.

References SendMailApp().

    {
        java.awt.EventQueue.invokeLater( 
                new Runnable() {
                    public void run() {
                        new SendMailApp ().setVisible( true );
                    }
                }
            );
    }
static String SendMailApp.now (  ) [static, private]

Gets current time stamp.

Returns:
time in ISO format

Definition at line 414 of file SendMailApp.java.

Referenced by println().

    {
        Calendar cal = Calendar.getInstance ();
        SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        return sdf.format( cal.getTime() );
    }
void SendMailApp.onSendCompleted ( String  errorMessage ) [virtual]

On send completed call-back.

Parameters:
errorMessagecontains an error message if not null, otherwise success

Implements MailTransport.Context.

Definition at line 442 of file SendMailApp.java.

References appTitle, MailTransport.getQueueSize(), mailTransport, and tabbedPane.

    {
        synchronized ( this )
        {
            int msgCount = mailTransport == null ? 0 : mailTransport.getQueueSize ();
            if ( msgCount == 0 ) {
                setTitle( appTitle + ", idle" );
            } else if ( msgCount == 1 ) {
                setTitle( appTitle + ", 1 message waiting to be sent..." );
            } else {
                setTitle( appTitle + ", " + msgCount 
                        + " messages waiting to be sent..." );
            }
        }

        if ( errorMessage != null ) {
            // tabbedPane.setSelectedIndex( 1 );
            tabbedPane.setForegroundAt( 1, Color.RED );
            tabbedPane.setTitleAt( 1, "MTA: Error!" );

            /* Commented because we don't want to disturb user...
             * 
            JOptionPane.showMessageDialog( this, 
                    "Failed to send e-mail messages from queue!\n"
                    + "Please, check the log for more details...\n"
                    + errorMessage,
                    "Error while flushing the queue...", 
                    JOptionPane.ERROR_MESSAGE );
            */
        } else {
            tabbedPane.setForegroundAt( 1, new Color( 0, 128, 0 ) ); // dark green
            tabbedPane.setTitleAt( 1, "MTA: OK" );
        }
    }
void SendMailApp.println ( String  str ) [virtual]

Logs message terminated with new line.

Parameters:
strmessage that will be logged

Implements MailTransport.Context.

Definition at line 427 of file SendMailApp.java.

References logArea, and now().

Referenced by enqueueMessage().

    {
        synchronized( logArea )
        {
            logArea.append( now () + "  " + str + "\n" );
            logArea.setRows( logArea.getRows () + 1 );
            logArea.setCaretPosition( logArea.getText().length () );
        }
    }

Member Data Documentation

final String SendMailApp.appTitle = "IP1-6.1: SMTP Send Mail" [static, private]

Common application title prefix.

Definition at line 43 of file SendMailApp.java.

Referenced by enqueueMessage(), onSendCompleted(), and SendMailApp().

JButton SendMailApp.buttonEnqueue [private]

GUI components.

Definition at line 48 of file SendMailApp.java.

Referenced by SendMailApp().

JButton SendMailApp.buttonSend [private]

Definition at line 49 of file SendMailApp.java.

Referenced by actionPerformed(), and SendMailApp().

JTextField SendMailApp.fieldFrom [private]

Definition at line 54 of file SendMailApp.java.

Referenced by enqueueMessage(), and SendMailApp().

JTextField SendMailApp.fieldServer [private]

Definition at line 52 of file SendMailApp.java.

Referenced by enqueueMessage(), and SendMailApp().

JTextField SendMailApp.fieldSubject [private]

Definition at line 58 of file SendMailApp.java.

Referenced by enqueueMessage(), and SendMailApp().

JTextField SendMailApp.fieldTo [private]

Definition at line 56 of file SendMailApp.java.

Referenced by enqueueMessage(), and SendMailApp().

JLabel SendMailApp.labelFrom [private]

Definition at line 53 of file SendMailApp.java.

Referenced by SendMailApp().

JLabel SendMailApp.labelServer [private]

Definition at line 51 of file SendMailApp.java.

Referenced by SendMailApp().

JLabel SendMailApp.labelSubject [private]

Definition at line 57 of file SendMailApp.java.

Referenced by SendMailApp().

JLabel SendMailApp.labelTo [private]

Definition at line 55 of file SendMailApp.java.

Referenced by SendMailApp().

JTextArea SendMailApp.logArea [private]

Definition at line 65 of file SendMailApp.java.

Referenced by clearLog(), println(), and SendMailApp().

JScrollPane SendMailApp.logPane [private]

Definition at line 64 of file SendMailApp.java.

Referenced by SendMailApp().

Instance of the current mail transport channel.

Definition at line 70 of file SendMailApp.java.

Referenced by enqueueMessage(), formWindowClosing(), and onSendCompleted().

JTextArea SendMailApp.messageContents [private]

Definition at line 60 of file SendMailApp.java.

Referenced by enqueueMessage(), and SendMailApp().

JScrollPane SendMailApp.messageScrollPane [private]

Definition at line 59 of file SendMailApp.java.

Referenced by SendMailApp().

final long SendMailApp.serialVersionUID = 6679954030573701419L [static, private]

Implements java.io.Serializable interface.

Definition at line 38 of file SendMailApp.java.

JTabbedPane SendMailApp.tabbedPane [private]

Definition at line 62 of file SendMailApp.java.

Referenced by enqueueMessage(), onSendCompleted(), and SendMailApp().


The documentation for this class was generated from the following file: