Question

I am trying to "connect" two classes together, MyJFrame and MySerialPort, using the interface SerialPortListener, but I am clueless as how to do it. The reason I am doing this is because yesterday I had a problem assigning data from a serial port buffer to a global String (finalString), in the MySerialPort class. This string should be returned to MyJFrame where a label displays it. The problem was that my label would display finalString before anything was assigned to finalString, since classes were running in different threads. I posted the question on the forum and received a suggestion to use interface to connect their threads, and I modified the code according. Where do I use the keyword implements SerialPortListener and how do I get the value?

SerialPortListener Interface code

public interface SerialPortListener {

    void stringReveivedFromSerialPort(String s);

}

MyJFrame class code

public class MyJFrame extends JFrame{

    public MySerialPorts msp = new MySerialPorts();


    public MyJFrame(){

        initComponents();//draws GUI components
        initSerialPorts();//initializes serial ports

    }

    private void initSerialPorts(){

        msp.getPortName();//gets serial port's name (in this example COM1)
        msp.openPort();//opens the communication for port COM1

    }

    private String firmwareVersion(){
    //This is the method I call when I want to get the Firmware Version

        msp.getFirmwareVersion();//sends command to receive reply from serial device
        lblFirmwareVersion.setText();//label that prints the firmware version String

    }

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MainJFrame().setVisible(true);
            }
        });
    }

    private JLabel lblFirmwareVersion;

}

MySerialPort class code

public class MySerialPort {

//this method is using the jSSC API (java simple serial connector)
//http://code.google.com/p/java-simple-serial-connector/

    private SerialPort serialPort;
    private int iBaudRate = SerialPort.BAUDRATE_57600;
    private int iDataBits = SerialPort.DATABITS_8;
    private int iStopBits = SerialPort.STOPBITS_1;
    private int iParity = SerialPort.PARITY_NONE;
    private String portName = "";
// private String finalString = "";
//  private StringBuilder sbBuffer = new StringBuilder();

    private List<SerialPortListener> portListeners = new ArrayList<SerialPortListenerInterface>();

    public void addMyPortListener(SerialPortListener listener) {
        portListeners.add(listener);
    }

    public void removeMyPortListener(SerialPortListener listener) {
        portListeners.remove(listener);
    }

    public void getFirmwareVersion() {
        sendPortCommand("<VersFV1A2>\r\n");
    }

//    public String returnFinalString() {
//        return finalString;
//    }

    public void getPortName() {
        String[] ports = SerialPortList.getPortNames();
        portName = ports[0];
    }

    public void openPort() {

        serialPort = new SerialPort(portName);

        try {

            if (serialPort.openPort()) {

                if (serialPort.setParams(iBaudRate, iDataBits, iStopBits, iParity)) {

                    serialPort.addEventListener(new Reader(), SerialPort.MASK_RXCHAR
                            | SerialPort.MASK_RXFLAG
                            | SerialPort.MASK_CTS
                            | SerialPort.MASK_DSR
                            | SerialPort.MASK_RLSD);

                } else {
                    //Error Message - Can't set selected port parameters!
                    serialPort.closePort();
                }

            } else {
                    //Error Message - Can't open port!
            }
        } catch (SerialPortException | HeadlessException ex) {
            //Error Message - Can't open port! - Do nothing    
        }
    }

    private void sendPortCommand(String sSendPortCommand) {

        if (sSendPortCommand.length() > 0) {

            try {
                serialPort.writeBytes(sSendPortCommand.getBytes());
            } catch (Exception ex) {
                //Error Message - Error occured while sending data!
            }
        }
    }

    private class Reader implements SerialPortEventListener {

        private String sBuffer = "";

        @Override
        public void serialEvent(SerialPortEvent spe) {

            if (spe.isRXCHAR() || spe.isRXFLAG()) {

                if (spe.getEventValue() > 0) {

                    try {

                        //Read chars from buffer
                        byte[] bBuffer = serialPort.readBytes(spe.getEventValue());
                        sBuffer = new String(bBuffer);

                        SwingUtilities.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                for (SerialPortListenerInterface listener : portListeners) {
                                    listener.stringReveivedFromSerialPort(sBuffer);
                                }
                            }
                        });

// The following is the code I had prior to suggestion of using invokeLater instead of invokeAndWait
//
//                        sbBuffer.setLength(0);
//
//                        SwingUtilities.invokeAndWait(
//                                new Runnable() {
//
//                                    @Override
//                                    public void run() {
//                                        sbBuffer.append(sBuffer);
//                                    }
//                                });
//
//                        finalString = new String(sbBuffer);

                    } catch (Exception ex) {
                    }

                }
            }
        }
    }
}
Was it helpful?

Solution

Here's some code that you could add to your initSerialPorts() method, and which would open a dialog box displaying the text received from the serial port:

msp.addMyPortListener(new SerialPortListener() {
    @Override
    public void stringReveivedFromSerialPort(String s) {
        JOptionPane.showMessageDialog(MyJFrame.this, s);
    }
});

It creates an anonymous SerialPortListener instance, which displays a dialog box containing the received text as message, and adds it to your MySerialPort msp instance.

OTHER TIPS

I believe that you want your MyJFrame class to implement SerialPortListener:

public class MyJFrame extends JFrame implements SerialPortListener {
  /* blah */
  @Override
  public void stringReveivedFromSerialPort(String s) {
    lblFirmwareVersion.setText(s);
  }
  /* blah */
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top