我正在尝试使用 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) {
}
}
}
}
}
}