0

我正在尝试使用 SerialPortListener 接口将 MyJFrame 和 MySerialPort 这两个类“连接”在一起,但我不知道该怎么做。我这样做的原因是因为昨天我在 MySerialPort 类中将数据从串行端口缓冲区分配给全局字符串 (finalString) 时遇到了问题。此字符串应返回到 MyJFrame,其中有一个标签显示它。问题是我的标签会在将任何内容分配给 finalString 之前显示 finalString,因为类在不同的线程中运行。我在论坛上发了这个问题,收到了一个使用接口连接他们的线程的建议,我据此修改了代码。我在哪里使用关键字实现 SerialPortListener以及如何获取值?

SerialPortListener 接口代码

public interface SerialPortListener {

    void stringReveivedFromSerialPort(String s);

}

MyJFrame 类代码

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 类代码

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) {
                    }

                }
            }
        }
    }
}
4

2 回答 2

1

我相信您希望您的MyJFrame班级实施SerialPortListener

public class MyJFrame extends JFrame implements SerialPortListener {
  /* blah */
  @Override
  public void stringReveivedFromSerialPort(String s) {
    lblFirmwareVersion.setText(s);
  }
  /* blah */
}
于 2012-03-01T18:07:00.990 回答
1

下面是一些可以添加到initSerialPorts()方法中的代码,它会打开一个对话框,显示从串行端口接收到的文本:

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

它创建一个匿名SerialPortListener实例,该实例显示一个对话框,其中包含作为消息接收到的文本,并将其添加到您的MySerialPort msp实例中。

于 2012-03-01T18:01:50.323 回答