This is my first ever project and first GUI. I have finished it (with help from Stack Overflow) and it works but is very slow. Can anyone suggest improvements for speed, best practices or usability.?It currently takes 16 seconds from pressing run in Eclipse to something appearing on my screen.  You will need RXTX lib to run it.  This is my GUI:import gnu.io.CommPort;import gnu.io.CommPortIdentifier;import gnu.io.NoSuchPortException;import gnu.io.SerialPort;import java.util.HashMap;import java.awt.EventQueue;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.event.MouseAdapter;import java.io.IOException;import java.io.OutputStream;import java.io.PrintStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.border.EmptyBorder;import javax.swing.JButton;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;import java.awt.GridBagLayout;import java.awt.GridBagConstraints;import java.awt.Insets;import javax.swing.JTextArea;import javax.swing.JLabel;import javax.swing.JComboBox;import javax.swing.SwingUtilities;import java.awt.Window.Type;import java.awt.Frame;import java.awt.Rectangle;import java.io.IOException;import javax.swing.JTextField;import javax.swing.JScrollPane;public class EBIAlarmUI extends JFrame {private static final long serialVersionUID = 16022014;public TwoWaySerialComm twoWaySerCom;/** * Start the GUI */public static void main(String[] args) {    EventQueue.invokeLater(new Runnable() {        public void run() {            try {                EBIAlarmUI frame = new EBIAlarmUI();                frame.setVisible(true);            } catch (Exception e) {                e.printStackTrace();            }        }    });}/** * Create the frame. */public EBIAlarmUI() {    initComponents();    twoWaySerCom = new TwoWaySerialComm();    redirectSystemStreams();}private void initComponents(){    setBounds(new Rectangle(0, 0, 1000, 600));    setExtendedState(Frame.MAXIMIZED_HORIZ);    setType(Type.POPUP);    setAlwaysOnTop(true);    setTitle(Alarm Generator);    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    GridBagLayout gridBagLayout = new GridBagLayout();    gridBagLayout.columnWidths = new int[]{0, 118, 0, 0, 0, 0, 0, 17, 23, 0, 0};    gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0};    gridBagLayout.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};    gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};    getContentPane().setLayout(gridBagLayout);    JLabel setComPortLabel = new JLabel(Com Port);    GridBagConstraints gbc_setComPortLabel = new GridBagConstraints();    gbc_setComPortLabel.anchor = GridBagConstraints.EAST;    gbc_setComPortLabel.insets = new Insets(0, 0, 5, 5);    gbc_setComPortLabel.gridx = 0;    gbc_setComPortLabel.gridy = 2;    getContentPane().add(setComPortLabel, gbc_setComPortLabel);    comPortcomboBox = new JComboBox();    comPortcomboBox.setEnabled(true);    setComPortLabel.setLabelFor(comPortcomboBox);    GridBagConstraints gbc_comPortcomboBox = new GridBagConstraints();    gbc_comPortcomboBox.fill = GridBagConstraints.HORIZONTAL;    gbc_comPortcomboBox.insets = new Insets(0, 0, 5, 5);    gbc_comPortcomboBox.gridx = 1;    gbc_comPortcomboBox.gridy = 2;    getContentPane().add(comPortcomboBox, gbc_comPortcomboBox);    Enumeration portList = CommPortIdentifier.getPortIdentifiers();    while (portList.hasMoreElements()) {      CommPortIdentifier cpi = (CommPortIdentifier) portList.nextElement();      if (cpi.getPortType() == CommPortIdentifier.PORT_SERIAL) {              comPortcomboBox.addItem(cpi.getName());        }      }     comPortcomboBox.addActionListener(new java.awt.event.ActionListener() {            public void actionPerformed(java.awt.event.ActionEvent evt) {                comPortcomboBoxActionPerformed(evt);            }    public void comPortcomboBoxActionPerformed(java.awt.event.ActionEvent evt) {        comPortcomboBox.getSelectedItem();     }});    alarm1Button = new JButton();    alarm1Button.setText(Alarm 1);    GridBagConstraints gbc_alarm1Button = new GridBagConstraints();    gbc_alarm1Button.insets = new Insets(0, 0, 5, 0);    gbc_alarm1Button.gridx = 9;    gbc_alarm1Button.gridy = 2;    getContentPane().add(alarm1Button, gbc_alarm1Button);    alarm1Button.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            alarm1ButtonActionPerformed(evt);        }        public synchronized void alarm1ButtonActionPerformed(                java.awt.event.ActionEvent evt) {            resultsTextArea.setText(Alarm 1 Activated, String:  + alarm1);            try {                byte[] b = alarm1.getBytes(ASCII);                TwoWaySerialComm.SerialWriter sw = new TwoWaySerialComm.SerialWriter(                        twoWaySerCom.serialPort.getOutputStream());                sw.out.write(b);            } catch (IOException e) {                // Do something to handle the exception                e.printStackTrace();            }        }    });    JButton alarm2Button = new JButton(Alarm 2);    alarm2Button.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            alarm2ButtonActionPerformed(evt);        }        public synchronized void alarm2ButtonActionPerformed(                java.awt.event.ActionEvent evt) {            resultsTextArea.setText(Alarm 2 Activated, String:  + alarm2);            try {                byte[] b = alarm2.getBytes(ASCII);                TwoWaySerialComm.SerialWriter sw = new TwoWaySerialComm.SerialWriter(                        twoWaySerCom.serialPort.getOutputStream());                sw.out.write(b);            } catch (IOException e) {                // Do something to handle the exception                e.printStackTrace();            }        }    });    JLabel setBaudRateLabel = new JLabel(Baud Rate);    GridBagConstraints gbc_setBaudRateLabel = new GridBagConstraints();    gbc_setBaudRateLabel.anchor = GridBagConstraints.EAST;    gbc_setBaudRateLabel.insets = new Insets(0, 0, 5, 5);    gbc_setBaudRateLabel.gridx = 0;    gbc_setBaudRateLabel.gridy = 3;    getContentPane().add(setBaudRateLabel, gbc_setBaudRateLabel);    baudRatecomboBox = new JComboBox(baudRates);    baudRatecomboBox.setSelectedIndex(2);    setBaudRateLabel.setLabelFor(baudRatecomboBox);    GridBagConstraints gbc_baudRateComboBox = new GridBagConstraints();    gbc_baudRateComboBox.fill = GridBagConstraints.HORIZONTAL;    gbc_baudRateComboBox.insets = new Insets(0, 0, 5, 5);    gbc_baudRateComboBox.gridx = 1;    gbc_baudRateComboBox.gridy = 3;    getContentPane().add(baudRatecomboBox, gbc_baudRateComboBox);    GridBagConstraints gbc_alarm2Button = new GridBagConstraints();    gbc_alarm2Button.insets = new Insets(0, 0, 5, 0);    gbc_alarm2Button.gridx = 9;    gbc_alarm2Button.gridy = 3;    getContentPane().add(alarm2Button, gbc_alarm2Button);    JButton alarm3Button = new JButton(Alarm 3);    alarm3Button.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            alarm3ButtonActionPerformed(evt);        }        public synchronized void alarm3ButtonActionPerformed(                java.awt.event.ActionEvent evt) {            resultsTextArea.setText(Alarm 3 Activated, String:  + alarm3);            try {                byte[] b = alarm3.getBytes(ASCII);                TwoWaySerialComm.SerialWriter sw = new TwoWaySerialComm.SerialWriter(                        twoWaySerCom.serialPort.getOutputStream());                sw.out.write(b);            } catch (IOException e) {                // Do something to handle the exception                e.printStackTrace();            }        }    });    JLabel lblDataBits = new JLabel(Data Bits);    GridBagConstraints gbc_lblDataBits = new GridBagConstraints();    gbc_lblDataBits.insets = new Insets(0, 0, 5, 5);    gbc_lblDataBits.anchor = GridBagConstraints.EAST;    gbc_lblDataBits.gridx = 0;    gbc_lblDataBits.gridy = 4;    getContentPane().add(lblDataBits, gbc_lblDataBits);    dataBitscomboBox = new JComboBox(dataBits);    dataBitscomboBox.setSelectedIndex(1);    GridBagConstraints gbc_dataBitscomboBox = new GridBagConstraints();    gbc_dataBitscomboBox.insets = new Insets(0, 0, 5, 5);    gbc_dataBitscomboBox.fill = GridBagConstraints.HORIZONTAL;    gbc_dataBitscomboBox.gridx = 1;    gbc_dataBitscomboBox.gridy = 4;    getContentPane().add(dataBitscomboBox, gbc_dataBitscomboBox);    GridBagConstraints gbc_alarm3Button = new GridBagConstraints();    gbc_alarm3Button.insets = new Insets(0, 0, 5, 0);    gbc_alarm3Button.gridx = 9;    gbc_alarm3Button.gridy = 4;    getContentPane().add(alarm3Button, gbc_alarm3Button);    JLabel lblStopBits = new JLabel(Stop Bits);    GridBagConstraints gbc_lblStopBits = new GridBagConstraints();    gbc_lblStopBits.insets = new Insets(0, 0, 5, 5);    gbc_lblStopBits.anchor = GridBagConstraints.EAST;    gbc_lblStopBits.gridx = 0;    gbc_lblStopBits.gridy = 5;    getContentPane().add(lblStopBits, gbc_lblStopBits);    stopBitscomboBox = new JComboBox(stopBits);    stopBitscomboBox.setSelectedIndex(1);    GridBagConstraints gbc_stopBitscomboBox = new GridBagConstraints();    gbc_stopBitscomboBox.insets = new Insets(0, 0, 5, 5);    gbc_stopBitscomboBox.fill = GridBagConstraints.HORIZONTAL;    gbc_stopBitscomboBox.gridx = 1;    gbc_stopBitscomboBox.gridy = 5;    getContentPane().add(stopBitscomboBox, gbc_stopBitscomboBox);    JButton customAlarmButton = new JButton(Custom Alarm);    GridBagConstraints gbc_customAlarmButton = new GridBagConstraints();    gbc_customAlarmButton.insets = new Insets(0, 0, 5, 0);    gbc_customAlarmButton.gridx = 9;    gbc_customAlarmButton.gridy = 5;    getContentPane().add(customAlarmButton, gbc_customAlarmButton);    customAlarmButton.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            customAlarmButtonActionPerformed(evt);        }        public void customAlarmButtonActionPerformed(java.awt.event.ActionEvent evt) {                resultsTextArea.setText(Custom alarm, string sent: + customStringTextArea.getText());                try {                    byte[] b = customStringTextArea.getText().toString().getBytes(ASCII);                    TwoWaySerialComm.SerialWriter sw = new TwoWaySerialComm.SerialWriter(                            twoWaySerCom.serialPort.getOutputStream());                    sw.out.write(b);                } catch (IOException e) {                    // Do something to handle the exception                    e.printStackTrace();                }            }        });    JLabel lblParity = new JLabel(Parity);    GridBagConstraints gbc_lblParity = new GridBagConstraints();    gbc_lblParity.insets = new Insets(0, 0, 5, 5);    gbc_lblParity.anchor = GridBagConstraints.EAST;    gbc_lblParity.gridx = 0;    gbc_lblParity.gridy = 6;    getContentPane().add(lblParity, gbc_lblParity);    paritycomboBox = new JComboBox(parity);    paritycomboBox.setSelectedIndex(0);    GridBagConstraints gbc_paritycomboBox = new GridBagConstraints();    gbc_paritycomboBox.insets = new Insets(0, 0, 5, 5);    gbc_paritycomboBox.fill = GridBagConstraints.HORIZONTAL;    gbc_paritycomboBox.gridx = 1;    gbc_paritycomboBox.gridy = 6;    getContentPane().add(paritycomboBox, gbc_paritycomboBox);    JLabel customStringAreaLabel = new JLabel(Enter Custom String:);    GridBagConstraints gbc_customStringAreaLabel = new GridBagConstraints();    gbc_customStringAreaLabel.insets = new Insets(0, 0, 5, 5);    gbc_customStringAreaLabel.gridx = 6;    gbc_customStringAreaLabel.gridy = 6;    getContentPane().add(customStringAreaLabel, gbc_customStringAreaLabel);    customStringTextArea = new JTextArea();    GridBagConstraints gbc_customStringTextArea = new GridBagConstraints();    gbc_customStringTextArea.gridwidth = 3;    gbc_customStringTextArea.insets = new Insets(0, 0, 5, 0);    gbc_customStringTextArea.fill = GridBagConstraints.BOTH;    gbc_customStringTextArea.gridx = 7;    gbc_customStringTextArea.gridy = 6;    getContentPane().add(customStringTextArea, gbc_customStringTextArea);    customStringTextArea.setText(Enter Custom String Here);    customStringTextArea.addMouseListener(new java.awt.event.MouseAdapter() {        public void mousePressed(java.awt.event.MouseEvent evt) {            customStringTextAreaMousePressed(evt);        }         private void customStringTextAreaMousePressed(java.awt.event.MouseEvent evt) {             customStringTextArea.setText();        }        });    openComportButton = new JButton(Open);    GridBagConstraints gbc_openComportButton = new GridBagConstraints();    gbc_openComportButton.anchor = GridBagConstraints.NORTH;    gbc_openComportButton.insets = new Insets(0, 0, 0, 5);    gbc_openComportButton.gridx = 0;    gbc_openComportButton.gridy = 7;    getContentPane().add(openComportButton, gbc_openComportButton);    openComportButton.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            openComportButtonActionPerformed(evt);        }        public synchronized void openComportButtonActionPerformed(                java.awt.event.ActionEvent evt)  {            resultsTextArea.setText(Com Port Opened);            String port = (String)comPortcomboBox.getSelectedItem();            String rate = (String)baudRatecomboBox.getSelectedItem();            String data = (String)dataBitscomboBox.getSelectedItem();            String stop = (String)stopBitscomboBox.getSelectedItem();            int parity = (int)paritycomboBox.getSelectedIndex();            int rateInt = Integer.parseInt(rate);            int dataInt = Integer.parseInt(data);            int stopInt = Integer.parseInt(stop);            if (port != null && rate != null && data != null && stop != null) {                        try {                            twoWaySerCom.connect(port, rateInt, dataInt, stopInt, parity);                        } catch (Exception e) {                            e.printStackTrace();                        }                    }         }    });    closeComportButton = new JButton(Close);    GridBagConstraints gbc_closeComportButton = new GridBagConstraints();    gbc_closeComportButton.anchor = GridBagConstraints.NORTHWEST;    gbc_closeComportButton.insets = new Insets(0, 0, 0, 5);    gbc_closeComportButton.gridx = 1;    gbc_closeComportButton.gridy = 7;    getContentPane().add(closeComportButton, gbc_closeComportButton);    closeComportButton.addActionListener(new java.awt.event.ActionListener() {        public void actionPerformed(java.awt.event.ActionEvent evt) {            closeComportButtonActionPerformed(evt);        }        public synchronized void closeComportButtonActionPerformed(                java.awt.event.ActionEvent evt)  {            resultsTextArea.setText(Com Port Closed);            try {                twoWaySerCom.disconnect();            } catch (Exception e) {                e.printStackTrace();            }        }         });    JLabel resultAreaLabel = new JLabel(Result:);    GridBagConstraints gbc_resultAreaLabel = new GridBagConstraints();    gbc_resultAreaLabel.anchor = GridBagConstraints.NORTHEAST;    gbc_resultAreaLabel.insets = new Insets(0, 0, 0, 5);    gbc_resultAreaLabel.gridx = 6;    gbc_resultAreaLabel.gridy = 7;    getContentPane().add(resultAreaLabel, gbc_resultAreaLabel);    JScrollPane scrollPane = new JScrollPane();    GridBagConstraints gbc_scrollPane = new GridBagConstraints();    gbc_scrollPane.gridwidth = 8;    gbc_scrollPane.fill = GridBagConstraints.BOTH;    gbc_scrollPane.gridx = 7;    gbc_scrollPane.gridy = 7;    getContentPane().add(scrollPane, gbc_scrollPane);    resultsTextArea = new JTextArea();    scrollPane.setViewportView(resultsTextArea);    resultsTextArea.setLineWrap(true);}public void updateTextArea(final String text) {      SwingUtilities.invokeLater(new Runnable() {        public void run() {          resultsTextArea.append(text);        }      });    }    public void redirectSystemStreams() {      OutputStream out = new OutputStream() {        @Override        public void write(int b) throws IOException {          updateTextArea(String.valueOf((char) b));        }        @Override        public void write(byte[] b, int off, int len) throws IOException {          updateTextArea(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));    }public javax.swing.JTextArea resultsTextArea;public javax.swing.JTextArea customStringTextArea;public javax.swing.JButton alarm1Button;public javax.swing.JButton alarm2Button;public javax.swing.JButton alarm3Button;public javax.swing.JButton customAlarmButton;public javax.swing.JButton openComportButton;public javax.swing.JButton closeComportButton;protected HashMap map = new HashMap();public javax.swing.JComboBox comPortcomboBox;public javax.swing.JComboBox baudRatecomboBox;public javax.swing.JComboBox dataBitscomboBox;public javax.swing.JComboBox stopBitscomboBox;public javax.swing.JComboBox paritycomboBox;String alarm1 = 81 01 06 01 00 10 03 01 FF;String alarm2 = *993R03,67,6#;String alarm3 = *994R14,67,1#;String[] parity = { none, odd, even, mark };String[] baudRates = { 2400, 4800, 9600, 14400, 19200, 38400, 56000, 115200  };String[] stopBits = { 0, 1  };String[] dataBits = { 7, 8  };}And this is where my comm port is opened and closed:import gnu.io.CommPort;import gnu.io.CommPortIdentifier;import gnu.io.SerialPort;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class TwoWaySerialComm {SerialPort serialPort;public TwoWaySerialComm() {    super();}public synchronized void connect(String port, int rateInt, int dataInt, int stopInt, int parity) throws Exception {    CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port);    if (portIdentifier.isCurrentlyOwned()) {        System.out.println(Error: Port is currently in use);    } else {        CommPort commPort = portIdentifier.open(this.getClass().getName(),                2000);        if (commPort instanceof SerialPort) {            serialPort = (SerialPort) commPort;            serialPort.setSerialPortParams(rateInt, dataInt, stopInt, parity);            InputStream in = serialPort.getInputStream();            OutputStream out = serialPort.getOutputStream();            (new Thread(new SerialReader(in))).start();            (new Thread(new SerialWriter(out))).start();        } else {            System.out                    .println(Error: Only serial ports are handled by this.);        }    }}public synchronized void disconnect() throws Exception {    if (serialPort != null) {        InputStream in = serialPort.getInputStream();        OutputStream out = serialPort.getOutputStream();        try {            serialPort.removeEventListener();            in.close();            out.close();        } catch (IOException ex) {        }        serialPort.close();    }}/** */public class SerialReader implements Runnable {    InputStream in;    public SerialReader(InputStream in) {        this.in = in;    }    public void run() {        byte[] buffer = new byte[1024];        int len = -1;        try {            while ((len = this.in.read(buffer)) > -1) {                System.out.print(new String(buffer, 0, len));            }        } catch (IOException e) {            e.printStackTrace();        }    }}/** */public static class SerialWriter implements Runnable {    OutputStream out;    public SerialWriter(OutputStream out) {        this.out = out;    }    public void run() {        try {            int c = 0;            while ((c = System.in.read()) > -1) {                this.out.write(c);                System.out.println(c);            }        } catch (IOException e) {            e.printStackTrace();        }    }}}
Open a comm port and send an ASCII string
java;serial port
Finding Performance ProblemsIt currently takes 16 seconds from pressing run in Eclipse to something appearing on my screen.The first step to fixing this is to find out what is causing the delay. My first assumption would be that it is the hardware on the other end of the connection, but who knows. To figure this out, you can do two things:Mock the TwoWaySerialComm object, so that there is no real communication with any external device. If your performance problems go away, you know it's not the GUI, but the external device, or the way you communicate with it*.Profile your code and see which methods take the longest.Before you don't know what the problem is, it will be hard to suggest improvements.* the communication itself seems to be happening in a different thread, but not the initial connection. As you say you have performance problems on startup, this might be an issue.StructureIt's really good that you put the connection stuff in it's own TwoWaySerialComm class. But right now, this class is hard to use, as you are printing in it, and swallowing exceptions. As you have a GUI, it would be nice to report errors in the GUI, not on the command line. So your TwoWaySerialComm class should throw exceptions instead of printing the errors.Your fields should also be private and accessed with getters.The biggest problem with your code structure is your GUI class though: It's way too big, and it has a method with 360 lines, which is just way too much. Nobody is going to read or understand that later on, and it makes your code very hard to extend, debug, profile, reuse, etc.This gigantic method also contains a lot of duplication, for example the alarmXButtonActionPerformed ActionListener are pretty much the same. Create an actual class for them, and pass the button as argument. This would already help quite a bit.If you then extract some of the GUI init code that logically belongs to each other to well-named functions, this would already be a great first step.Miscyour naming could be better in parts. Eg it took me a bit to figure out what gbc_lblParity are. Don't shorten names, and use java naming conventions (camelCase). parityLabel and parityGridBagConstraints (or parityConstraints) aren't all that long, but a lot clearer