Subversion Repositories Programming Utils

Rev

Rev 50 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.rm5248.terminal;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;

import com.rm5248.serial.NoSuchPortException;
import com.rm5248.serial.NotASerialPortException;
import com.rm5248.serial.SerialChangeListener;
import com.rm5248.serial.SerialLineState;
import com.rm5248.serial.SerialPort;
import com.rm5248.serial.SerialPort.BaudRate;
import com.rm5248.serial.SerialPort.DataBits;
import com.rm5248.serial.SerialPort.FlowControl;
import com.rm5248.serial.SerialPort.Parity;
import com.rm5248.serial.SerialPort.StopBits;

/**
 * JavaTerminal is a Java-based terminal emulator to open serial ports.
 * It is designed to be similar to GTKTerm for Linux.
 * GTKTerm's webpage is at https://fedorahosted.org/gtkterm/
 *
 *
 */

public class JavaTerminal implements KeyListener, Runnable {

        private enum NewlineType{
                CR,
                NL,
                CRNL
        }

        //SerialPort variables
        private SerialPort thePort;
        private InputStream portInput;
        private OutputStream portOutput;
        private boolean localEcho;
        private NewlineType newlines;

        //GUI variables
        private JFrame theFrame;
        private JLabel portInfoLeft;
        private LineIndicatorPanel portStatus;
        private JTextArea text;
        private Font monoFont;
        private Font sansFont;

        //The newline separator, so that we put the correct one in the GUI so copy/paste will work nicely
        private final static String NEWLINE = System.getProperty("line.separator");

        public JavaTerminal( String portToOpen, BaudRate baud, DataBits data, StopBits stop, Parity parity, FlowControl flow, boolean localEcho, boolean justOpen ){
                this.localEcho = localEcho;
                newlines = NewlineType.NL;

                try{
                        UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
                }catch( Exception e ){}

                makeGUI();

                try {
                        if( !justOpen ){
                                thePort = new SerialPort( portToOpen, baud, data, stop, parity, flow );
                        }else{
                                thePort = new SerialPort( portToOpen, justOpen );
                        }
                } catch (NoSuchPortException e) {
                        System.err.println( "ERROR: No Such Port( " + portToOpen + " )" );
                        System.err.println( "    " + e.getMessage() );
                        JOptionPane.showMessageDialog( null, "ERROR: No Such Port( " + portToOpen + ")\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE );
                        return;
                } catch (NotASerialPortException e) {
                        System.err.println( "ERROR: Not a serial port( " + portToOpen + " )" );
                        System.err.println( "    " + e.getMessage() );
                        JOptionPane.showMessageDialog( null, "ERROR: Not a serial port( " + portToOpen + ")", "Error", JOptionPane.ERROR_MESSAGE );
                        return;
                }

                portInput = thePort.getInputStream();
                portOutput = thePort.getOutputStream();

                new Thread( this, "Reading Thread" ).start();

                thePort.setSerialChangeListener( new SerialChangeListener() {

                        @Override
                        public void serialStateChanged(SerialLineState state) {
                                portStatus.setLineState( state );
                        }
                });
               
                SerialLineState newState = new SerialLineState();
                newState.dataTerminalReady = true;
                newState.requestToSend = true;
               
                thePort.setSerialLineState( newState );

                try {
                        portStatus.setLineState( thePort.getSerialLineState() );
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }

                updatePortInformation();

                /*new Thread( new Runnable() {

                        @Override
                        public void run() {
                                while( true ){
                                        try {
                                                System.out.println( thePort.getSerialLineState() );
                                                Thread.sleep( 1000 );
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                }
                        }
                }).start();
                 */

        }

        private void makeGUI(){
                //First let's get the fonts that we want to use
                try {
                        InputStream is = this.getClass().getResourceAsStream( "/fonts/LiberationMono-Regular.ttf" );
                        monoFont = Font.createFont( Font.TRUETYPE_FONT, is );
                        monoFont = monoFont.deriveFont( 18.0f );
                } catch ( Exception e ){
                        monoFont = new Font( "monospaced", Font.PLAIN, 18 );
                }

                try{
                        InputStream is = this.getClass().getResourceAsStream( "/fonts/LiberationSans-Regular.ttf" );
                        sansFont = Font.createFont( Font.TRUETYPE_FONT, is );
                        sansFont = sansFont.deriveFont( 12.0f );
                }catch( Exception e){
                        sansFont = new Font( "serif", Font.PLAIN, 12 );
                }

                theFrame = new JFrame( "JavaTerminal" );

                JPanel mainPanel = new JPanel( new BorderLayout() );

                JPanel statusPanel = new JPanel( new BorderLayout() );
                statusPanel.add( portInfoLeft = new JLabel(), BorderLayout.WEST );
                statusPanel.add( portStatus = new LineIndicatorPanel(), BorderLayout.EAST );
                statusPanel.setPreferredSize( new Dimension( 20, 20 ) );

                portInfoLeft.setFont( sansFont );
                portInfoLeft.setForeground( Color.DARK_GRAY );

                text = new JTextArea();
                text.setBackground( Color.BLACK );
                text.setForeground( Color.LIGHT_GRAY );

                text.setFont( monoFont );
                text.setColumns( 80 );
                text.setEditable( false );
                text.addKeyListener( this );

                JScrollPane scrollPane = new JScrollPane( text );
                scrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
                scrollPane.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
                mainPanel.add( scrollPane );
                mainPanel.add( statusPanel, BorderLayout.SOUTH );

                //Make our menus
                JMenuBar menuBar = new JMenuBar();
                //Make our file menu
                JMenu fileMenu = new JMenu( "File" );
                fileMenu.setMnemonic( KeyEvent.VK_F );
                JMenuItem exitItem = new JMenuItem( "Exit" );
                exitItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_Q, KeyEvent.VK_ALT ) );
                exitItem.addActionListener( new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                                System.exit( 0 );
                        }
                });
                fileMenu.add( exitItem );
                menuBar.add( fileMenu );
                //Make config menu
                JMenu configMenu = new JMenu( "Configuration" );
                configMenu.setMnemonic( KeyEvent.VK_C );
                JMenuItem port = new JMenuItem( "Port" );
                port.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.VK_ALT ) );
                port.addActionListener( new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                                JFrame settingFrame = new JFrame( "Configuration" );

                                JPanel mainPanel = new JPanel();

                                JPanel configPanel = new JPanel( new GridLayout( 4, 3 ) );
                                configPanel.setBorder( BorderFactory.createTitledBorder( "Serial port") );
                                configPanel.add( createDialogLabel( "Port:" ) );
                                configPanel.add( createDialogLabel( "Speed:" ) );
                                configPanel.add( createDialogLabel( "Parity:" ) );
                                final JComboBox port = new JComboBox();
                                port.setEditable( true );
                                if( thePort != null ){
                                        port.addItem( thePort.getPortName() );
                                }
                                configPanel.add( port );
                                final JComboBox speed = new JComboBox();
                                BaudRate[] values = BaudRate.values();
                                for( int x = 0; x < values.length; x++ ){
                                        speed.addItem( values[ x ] );
                                        if( thePort != null ){
                                                if( thePort.getBaudRate() == values[ x ] ){
                                                        speed.setSelectedIndex( x );
                                                }
                                        }
                                }
                                speed.setEditable( false );
                                configPanel.add( speed );
                                final JComboBox parity = new JComboBox();
                                Parity[] parityValues = Parity.values();
                                for( int x = 0; x < parityValues.length; x++ ){
                                        parity.addItem( parityValues[ x ] );
                                        if( thePort != null ){
                                                if( thePort.getParity() == parityValues[ x ] ){
                                                        parity.setSelectedIndex( x );
                                                }
                                        }
                                }
                                parity.setEditable( false );
                                configPanel.add( parity );
                                configPanel.add( createDialogLabel( "Bits:" ) );
                                configPanel.add( createDialogLabel( "Stopbits:" ) );
                                configPanel.add( createDialogLabel( "Flow control:" ) );
                                final JComboBox bits = new JComboBox();
                                DataBits[] dataValues = DataBits.values();
                                for( int x = 0; x < dataValues.length; x++ ){
                                        bits.addItem( dataValues[ x ] );
                                        if( thePort != null ){
                                                if( thePort.getDataBits() == dataValues[ x ] ){
                                                        bits.setSelectedIndex( x );
                                                }
                                        }
                                }
                                configPanel.add( bits );
                                final JComboBox stopbits = new JComboBox();
                                StopBits[] stopValues = StopBits.values();
                                for( int x = 0; x < stopValues.length; x++ ){
                                        stopbits.addItem( stopValues[ x ] );
                                        if( thePort != null ){
                                                if( thePort.getStopBits() == stopValues[ x ] ){
                                                        stopbits.setSelectedIndex( x );
                                                }
                                        }
                                }
                                configPanel.add( stopbits );
                                final JComboBox flow = new JComboBox();
                                FlowControl[] flowValues = FlowControl.values();
                                for( int x = 0; x < flowValues.length; x++ ){
                                        flow.addItem( flowValues[ x ] );
                                        if( thePort != null ){
                                                if( thePort.getFlowControl() == flowValues[ x ] ){
                                                        flow.setSelectedIndex( x );
                                                }
                                        }
                                }
                                configPanel.add( flow );

                                JPanel bottomPanel = new JPanel();
                                JButton applyButton = new JButton( "Apply" );
                                applyButton.addActionListener( new ActionListener() {

                                        @Override
                                        public void actionPerformed(ActionEvent e) {
                                                if( thePort == null || !thePort.getPortName().equals( port.getSelectedItem().toString() ) ){
                                                        if( thePort != null ){
                                                                thePort.close();
                                                        }

                                                        try {
                                                                thePort = new SerialPort( port.getName(), true );
                                                        } catch (NoSuchPortException e1) {
                                                                JOptionPane.showMessageDialog( null, "ERROR: " + port.getName() + " does not exist!", "Error", JOptionPane.ERROR_MESSAGE );
                                                                return;
                                                        } catch (NotASerialPortException e1) {
                                                                JOptionPane.showMessageDialog( null, "ERROR: " + port.getName() + " is not a serial port!", "Error", JOptionPane.ERROR_MESSAGE );
                                                                return;
                                                        }

                                                        portInput = thePort.getInputStream();
                                                        portOutput = thePort.getOutputStream();

                                                        try {
                                                                portStatus.setLineState( thePort.getSerialLineState() );
                                                        } catch (IOException ex) {
                                                                // TODO Auto-generated catch block
                                                                ex.printStackTrace();
                                                        }
                                                }

                                                BaudRate[] values = BaudRate.values();
                                                for( int x = 0; x < values.length; x++ ){
                                                        if( values[ x ].toString().equals( speed.getSelectedItem().toString() ) ){
                                                                thePort.setBaudRate( values[ x ] );
                                                        }
                                                }

                                                Parity[] parityValues = Parity.values();
                                                for( int x = 0; x < parityValues.length; x++ ){
                                                        if( parityValues[ x ].toString().equals( parity.getSelectedItem().toString() ) ){
                                                                thePort.setParity( parityValues[ x ] );
                                                        }
                                                }

                                                DataBits[] dataValues = DataBits.values();
                                                for( int x = 0; x < dataValues.length; x++ ){
                                                        if( dataValues[ x ].equals( bits.getSelectedItem() ) ){
                                                                thePort.setDataSize( dataValues[ x ] );
                                                        }
                                                }

                                                StopBits[] stopValues = StopBits.values();
                                                for( int x = 0; x < stopValues.length; x++ ){
                                                        if( stopValues[ x ].equals( stopbits.getSelectedItem() ) ){
                                                                thePort.setStopBits( stopValues[ x ] );
                                                        }
                                                }

                                                FlowControl[] flowValues = FlowControl.values();
                                                for( int x = 0; x < flowValues.length; x++ ){
                                                        if( flowValues[ x ].equals( flow.getSelectedItem() ) ){
                                                                thePort.setFlowControl( flowValues[ x ] );
                                                        }
                                                }

                                                updatePortInformation();
                                        }
                                });
                                bottomPanel.add( applyButton );

                                mainPanel.add( configPanel );
                                mainPanel.add( bottomPanel );
                                settingFrame.add( mainPanel );

                                settingFrame.setSize( 500, 300 );
                                settingFrame.setVisible( true );
                                settingFrame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
                        }
                });
                configMenu.add( port );
                JMenuItem window = new JMenuItem( "Main Window" );
                configMenu.add( window );
                final JCheckBoxMenuItem localEchoBox = new JCheckBoxMenuItem( "Local Echo" );
                localEchoBox.addActionListener( new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                                localEcho = localEchoBox.isSelected();
                        }
                });
                localEchoBox.setSelected( localEcho );
                configMenu.add( localEchoBox );
                configMenu.add( new JSeparator() );
                configMenu.add( new JMenuItem( "ENTER sends: " ) );
                ButtonGroup newlineGroup = new ButtonGroup();
                JRadioButtonMenuItem crButton = new JRadioButtonMenuItem( "CR (\\r)" );
                JRadioButtonMenuItem nlButton = new JRadioButtonMenuItem( "NL (\\n)" );
                JRadioButtonMenuItem crnlButton = new JRadioButtonMenuItem( "CR NL (\\r\\n)" );
                newlineGroup.add( crButton );
                newlineGroup.add( nlButton );
                newlineGroup.add( crnlButton );
                nlButton.setSelected( true );
                crButton.addActionListener( new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                                newlines = NewlineType.CR;
                        }
                });
                nlButton.addActionListener( new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                                newlines = NewlineType.NL;
                        }
                });
                crnlButton.addActionListener( new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                                newlines = NewlineType.CRNL;
                        }
                });
                configMenu.add( crButton );
                configMenu.add( nlButton );
                configMenu.add( crnlButton );
                configMenu.add( new JSeparator() );
                menuBar.add( configMenu );

                JMenu controlSigs = new JMenu( "Control Signals" );
                controlSigs.setMnemonic( KeyEvent.VK_S );
                JMenuItem sendBreak = new JMenuItem( "Send Break" );
                sendBreak.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_B, KeyEvent.VK_ALT ) );
                controlSigs.add( sendBreak );
                JMenuItem toggleDTR = new JMenuItem( "Toggle DTR" );
                toggleDTR.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F7, KeyEvent.ALT_DOWN_MASK & KeyEvent.CTRL_DOWN_MASK ) );
                toggleDTR.addActionListener( new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                                try{
                                        SerialLineState s = thePort.getSerialLineState();
                                        s.dataTerminalReady = !s.dataTerminalReady;
                                        thePort.setSerialLineState( s );
                                }catch( IOException e ){}
                        }
                });
                controlSigs.add( toggleDTR );
                JMenuItem toggleRTS = new JMenuItem( "Toggle RTS" );
                toggleRTS.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F8, KeyEvent.ALT_DOWN_MASK & KeyEvent.CTRL_DOWN_MASK ) );
                toggleRTS.addActionListener( new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent evt) {
                                try{
                                        SerialLineState s = thePort.getSerialLineState();
                                        s.requestToSend = !s.requestToSend;
                                        thePort.setSerialLineState( s );
                                }catch( IOException e ){}
                        }
                });
                controlSigs.add( toggleRTS );
                menuBar.add( controlSigs );

                JMenu view = new JMenu( "View" );
                view.setMnemonic( KeyEvent.VK_V );
                ButtonGroup asciiHexGroup = new ButtonGroup();
                JRadioButtonMenuItem ascii = new JRadioButtonMenuItem( "ASCII" );
                ascii.setSelected( true );
                asciiHexGroup.add( ascii );
                view.add( ascii );
                JRadioButtonMenuItem hex = new JRadioButtonMenuItem( "Hex" );
                asciiHexGroup.add( hex );
                view.add( hex );
                JMenu hexCharsSubMenu = new JMenu( "Hexadecimal chars" );
                hexCharsSubMenu.setEnabled( false );
                JMenuItem eightChars = new JMenuItem( "8" );
                hexCharsSubMenu.add( eightChars );
                JMenuItem tenChars = new JMenuItem( "10" );
                hexCharsSubMenu.add( tenChars );
                JMenuItem sixteenChars = new JMenuItem( "16" );
                hexCharsSubMenu.add( sixteenChars );
                JMenuItem twentyFourChars = new JMenuItem( "24" );
                hexCharsSubMenu.add( twentyFourChars );
                JMenuItem thirtyTwooChars = new JMenuItem( "32" );
                hexCharsSubMenu.add( thirtyTwooChars );
                view.add( hexCharsSubMenu );
                JMenuItem showIndex = new JMenuItem( "Show Index" );
                showIndex.setEnabled( false );
                view.add( showIndex );
                view.addSeparator();
                JMenuItem sendHexData = new JMenuItem( "Send Hex Data" );
                view.add( sendHexData );
                menuBar.add( view );

                JMenu help = new JMenu( "Help" );
                help.setMnemonic( KeyEvent.VK_H );
                JMenuItem about = new JMenuItem( "About" );
                about.addActionListener( new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                                JOptionPane.showMessageDialog( null, "JavaTerminal 0.X\n" +
                                                "From programming.rm5248.com\n\n\n" +
                                                "Java Serial version: " + String.format( "%d.%d", SerialPort.getMajorVersion(), SerialPort.getMinorVersion() ) + "\n"+
                                                "Java Serial Native Version: " + String.format( "%d.%d", SerialPort.getMajorNativeVersion(), SerialPort.getMinorNativeVersion() ) + "\n", "About", JOptionPane.INFORMATION_MESSAGE );
                        }
                });
                help.add( about );
                menuBar.add( help );

                //add everything to the frame
                theFrame.setJMenuBar( menuBar );
                theFrame.add( mainPanel );
                theFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                theFrame.setVisible( true );

                //Let's figure out how wide we should be in order to be 80 characters wide
                //We can only do this after the frame is visible.
                //85 characters wide because of the width of the window and scroll bar
                int width = 0;
                FontMetrics font = text.getGraphics().getFontMetrics( monoFont );
                width = font.charWidth( 'a' ) * 85;

                theFrame.setSize( width, 600 );

                updatePortInformation();
        }

        /**
         * @param args
         */

        public static void main(String[] args) {
                //Make defaults, then parse our arguments
                BaudRate baud = BaudRate.B9600;
                DataBits data = DataBits.DATABITS_8;
                StopBits stop = StopBits.STOPBITS_1;
                Parity parity = Parity.NONE;
                FlowControl flow = FlowControl.NONE;
                String portToOpen;
                boolean echo = false;
                boolean justOpen = false;

                if( System.getProperty( "os.name" ).toLowerCase().indexOf( "win" ) >= 0 ){
                        portToOpen = "COM1";
                }else{
                        portToOpen = "/dev/ttyS0";
                }

                for( int x = 0; x < args.length; x++ ){
                        if( args[ x ].equals( "--help" ) ||
                                        args[ x ].equals( "-h" ) ){
                                //Print out help
                                System.out.println( "JavaTerminal" );
                                System.out.println();
                                System.out.println( "Program Homepage: http://www.rm5248.com/JavaSerial" );
                                System.out.println();
                                System.out.println( "Command Line Options: " );
                                System.out.println( "--help or -h : This help screen" );
                                System.out.println( "--port=<port> or -p : Device to open (Default: " + portToOpen + ")" );
                                System.out.println( "--speed=<speed> or -s : Port Speed (Default: 9600)" );
                                System.out.println( "--bits=<bits> or -b : Number of bits (Default: 8)" );
                                System.out.println( "--stopbits=<bits> or -t : Number of stop bits (Defaults: 1)" );
                                System.out.println( "--parity=<odd|even|none> or -a : Parity (Default: None)" );
                                System.out.println( "--flow=<xon|cts|none> or -w : Flow Control (Default: None)" );
                                System.out.println( "--echo or -e : Switch on local echo" );
                                System.out.println( "--open or -o : Open the serial port, do not change settings" );
                                System.exit( 0 );
                        }else if( args[ x ].startsWith( "--port=" ) ){
                                portToOpen = args[ x ].substring( args[ x ].indexOf( '=' ) + 1 );
                        }else if( args[ x ].equals( "-p" ) && x < args.length ){
                                portToOpen = args[ ++x ];
                        }else if( args[ x ].startsWith( "--speed=" ) ){
                                int speed = 9600;

                                try{
                                        speed = Integer.parseInt( args[ x ].substring( args[ x ].indexOf( '=' ) + 1 ) );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: Speed was incorrect, assuming 9600" );
                                        speed = 9600;
                                }

                                switch( speed ){
                                case 0     :  baud = BaudRate.B0     ; break;
                                case 50    :  baud = BaudRate.B50    ; break;
                                case 75    :  baud = BaudRate.B75    ; break;
                                case 110   :  baud = BaudRate.B110   ; break;
                                case 134   :  baud = BaudRate.B134   ; break;
                                case 150   :  baud = BaudRate.B150   ; break;
                                case 200   :  baud = BaudRate.B200   ; break;
                                case 300   :  baud = BaudRate.B300   ; break;
                                case 600   :  baud = BaudRate.B600   ; break;
                                case 1200  :  baud = BaudRate.B1200  ; break;
                                case 1800  :  baud = BaudRate.B1800  ; break;
                                case 2400  :  baud = BaudRate.B2400  ; break;
                                case 4800  :  baud = BaudRate.B4800  ; break;
                                case 9600  :  baud = BaudRate.B9600  ; break;
                                case 38400 :  baud = BaudRate.B38400 ; break;
                                case 115200:  baud = BaudRate.B115200; break;
                                default:
                                        System.err.println( "ERROR: Speed was incorrect, assuming 9600" );
                                        baud = BaudRate.B9600;
                                }
                        }else if( args[ x ].equals( "-s" ) ){
                                int speed = 9600;

                                try{
                                        speed = Integer.parseInt( args[ ++x ] );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: Speed was incorrect, assuming 9600" );
                                        speed = 9600;
                                }

                                switch( speed ){
                                case 0     :  baud = BaudRate.B0     ; break;
                                case 50    :  baud = BaudRate.B50    ; break;
                                case 75    :  baud = BaudRate.B75    ; break;
                                case 110   :  baud = BaudRate.B110   ; break;
                                case 134   :  baud = BaudRate.B134   ; break;
                                case 150   :  baud = BaudRate.B150   ; break;
                                case 200   :  baud = BaudRate.B200   ; break;
                                case 300   :  baud = BaudRate.B300   ; break;
                                case 600   :  baud = BaudRate.B600   ; break;
                                case 1200  :  baud = BaudRate.B1200  ; break;
                                case 1800  :  baud = BaudRate.B1800  ; break;
                                case 2400  :  baud = BaudRate.B2400  ; break;
                                case 4800  :  baud = BaudRate.B4800  ; break;
                                case 9600  :  baud = BaudRate.B9600  ; break;
                                case 38400 :  baud = BaudRate.B38400 ; break;
                                case 115200:  baud = BaudRate.B115200; break;
                                default:
                                        System.err.println( "ERROR: Speed was incorrect, assuming 9600" );
                                        baud = BaudRate.B9600;
                                }
                        }else if( args[ x ].startsWith( "--bits=" ) ){
                                int bits = 8;

                                try{
                                        bits = Integer.parseInt( args[ x ].substring( args[ x ].indexOf( '=' ) + 1 ) );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: Bits were incorrect, assuming 8" );
                                        bits = 8;
                                }

                                switch( bits ){
                                case 8:
                                        data = DataBits.DATABITS_8; break;
                                case 7:
                                        data = DataBits.DATABITS_7; break;
                                case 6:
                                        data = DataBits.DATABITS_6; break;
                                case 5:
                                        data = DataBits.DATABITS_5; break;
                                default:
                                        data = DataBits.DATABITS_8;
                                }

                        }else if( args[ x ].equals( "-b" ) ){
                                int bits = 8;

                                try{
                                        bits = Integer.parseInt( args[ ++x ] );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: Bits were incorrect, assuming 8" );
                                        bits = 8;
                                }

                                switch( bits ){
                                case 8:
                                        data = DataBits.DATABITS_8; break;
                                case 7:
                                        data = DataBits.DATABITS_7; break;
                                case 6:
                                        data = DataBits.DATABITS_6; break;
                                case 5:
                                        data = DataBits.DATABITS_5; break;
                                default:
                                        data = DataBits.DATABITS_8;
                                }
                        }else if( args[ x ].startsWith( "--stopbits=" ) ){
                                int stopBits = 1;

                                try{
                                        stopBits = Integer.parseInt( args[ x ].substring( args[ x ].indexOf( '=' ) + 1 ) );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: StopBits were incorrect, assuming 1" );
                                        stopBits = 1;
                                }

                                switch( stopBits ){
                                case 2:
                                        stop = StopBits.STOPBITS_2; break;
                                case 1:
                                        stop = StopBits.STOPBITS_1; break;
                                default:
                                        stop = StopBits.STOPBITS_1;
                                        System.err.println( "ERROR: StopBits were incorrect, assuming 1" );
                                }
                        }else if( args[ x ].equals( "-t" ) ){
                                int stopBits = 1;

                                try{
                                        stopBits = Integer.parseInt( args[ ++x ] );
                                }catch( Exception e ){
                                        System.err.println( "ERROR: StopBits were incorrect, assuming 1" );
                                        stopBits = 1;
                                }

                                switch( stopBits ){
                                case 2:
                                        stop = StopBits.STOPBITS_2; break;
                                case 1:
                                        stop = StopBits.STOPBITS_1; break;
                                default:
                                        stop = StopBits.STOPBITS_1;
                                        System.err.println( "ERROR: StopBits were incorrect, assuming 1" );
                                }
                        }else if( args[ x ].startsWith( "--parity=" ) ){
                                String parityName = args[ x ].substring( args[ x ].indexOf( '=' ) + 1 );

                                if( parityName.equals( "odd" ) ){
                                        parity = Parity.ODD;
                                }else if( parityName.equals( "none" ) ){
                                        parity = Parity.NONE;
                                }else if( parityName.equals( "even" ) ){
                                        parity = Parity.EVEN;
                                }else{
                                        System.err.println( "ERROR: Parity was incorrect, assuming none" );
                                }
                        }else if( args[ x ].equals( "-a" ) ){
                                String parityName = args[ ++x ];

                                if( parityName.equals( "odd" ) ){
                                        parity = Parity.ODD;
                                }else if( parityName.equals( "none" ) ){
                                        parity = Parity.NONE;
                                }else if( parityName.equals( "even" ) ){
                                        parity = Parity.EVEN;
                                }else{
                                        System.err.println( "ERROR: Parity was incorrect, assuming none" );
                                }
                        }else if( args[ x ].startsWith( "--flow=" ) ){
                                String flowName = args[ x ].substring( args[ x ].indexOf( '=' ) + 1 );

                                if( flowName.equals( "xon" ) ){
                                        flow = FlowControl.SOFTWARE;
                                }else if( flowName.equals( "cts" ) ){
                                        flow = FlowControl.HARDWARE;
                                }else if( flowName.equals( "none" ) ){
                                        flow = FlowControl.NONE;
                                }else{
                                        System.err.println( "ERROR: Flow Control was incorrect, assuming none" );
                                }
                        }else if( args[ x ].equals( "-w" ) ){
                                String flowName = args[ ++x ];

                                if( flowName.equals( "xon" ) ){
                                        flow = FlowControl.SOFTWARE;
                                }else if( flowName.equals( "cts" ) ){
                                        flow = FlowControl.HARDWARE;
                                }else if( flowName.equals( "none" ) ){
                                        flow = FlowControl.NONE;
                                }else{
                                        System.err.println( "ERROR: Flow Control was incorrect, assuming none" );
                                }
                        }else if( args[ x ].equals( "--echo" ) || args[ x ].equals( "-e" ) ){
                                echo = true;
                        }else if( args[ x ].equals( "--open" ) || args[ x ].equals( "-o" ) ){
                                justOpen = true;
                        }
                } // end for loop

                new JavaTerminal( portToOpen, baud, data, stop, parity, flow, echo, justOpen );
        }

        @Override
        public void keyPressed(KeyEvent arg0) {}

        @Override
        public void keyReleased(KeyEvent arg0) {}

        @Override
        public void keyTyped(KeyEvent event) {
                String toWrite = "";

                if( portOutput == null ){
                        return;
                }

                if( localEcho ){
                        appendCharacter( event.getKeyChar() );
                }

                if( event.getKeyCode() == KeyEvent.VK_ENTER ){
                        if( newlines == NewlineType.NL ){
                                toWrite = "\n";
                        }else if( newlines == NewlineType.CR ){
                                toWrite = "\r";
                        }else if( newlines == NewlineType.CRNL ){
                                toWrite = "\r\n";
                        }
                }else{
                        toWrite = new String( event.getKeyChar() + "" );
                }

                try {
                        portOutput.write( toWrite.getBytes() );
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

        private void appendCharacter( char c ){
                try {
                        String lastLine = text.getText().substring( text.getLineStartOffset( text.getLineCount() - 1 ) );
                        if( lastLine.length() == 80 ){
                                text.append( NEWLINE );
                        }
                } catch (BadLocationException e) {}


                if( c == '\n' || c == '\r' ){
                        text.append( NEWLINE );
                }else{
                        text.append( c + "" );
                }
        }

        /**
         * Update the information in the lower left corner.
         */

        private void updatePortInformation(){
                int myRate = 0;
                int dataBits = 0;
                char parity = 'N';
                int stop = 0;

                if( thePort == null ){
                        portInfoLeft.setText( "No open port" );
                        return;
                }
                String txt = thePort.getPortName() + " : ";

                switch( thePort.getBaudRate() ){
                case B0     :  myRate = 0; break;
                case B50    :  myRate = 50; break;
                case B75    :  myRate = 75; break;
                case B110   :  myRate = 110; break;
                case B134   :  myRate = 134; break;
                case B150   :  myRate = 150; break;
                case B200   :  myRate = 200; break;
                case B300   :  myRate = 300; break;
                case B600   :  myRate = 600; break;
                case B1200  :  myRate = 1200; break;
                case B1800  :  myRate = 1800; break;
                case B2400  :  myRate = 2400; break;
                case B4800  :  myRate = 4800; break;
                case B9600  :  myRate = 9600; break;
                case B38400 :  myRate = 38400; break;
                case B115200:  myRate = 115200; break;
                }

                switch( thePort.getDataBits() ){
                case DATABITS_5: dataBits = 5; break;
                case DATABITS_6: dataBits = 6; break;
                case DATABITS_7: dataBits = 7; break;
                case DATABITS_8: dataBits = 8; break;
                }

                switch( thePort.getParity() ){
                case NONE: parity = 'N'; break;
                case ODD: parity = 'O'; break;
                case EVEN: parity = 'E'; break;
                }

                switch( thePort.getStopBits() ){
                case STOPBITS_1: stop = 1; break;
                case STOPBITS_2: stop = 2; break;
                }

                txt += myRate + ",";
                txt += dataBits + ",";
                txt += parity + ",";
                txt += stop;

                portInfoLeft.setText( txt );
        }

        @Override
        public void run() {
                while( true ){
                        try {
                                appendCharacter( (char)portInput.read() );
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }

        }

        private JLabel createDialogLabel( String title ){
                JLabel lbl = new JLabel( title );
                lbl.setFont( this.sansFont );
                lbl.setAlignmentY( JLabel.CENTER_ALIGNMENT );
                return lbl;
        }

}