java-为线程实现接口
我试图使用SerialPortListener接口将两个类“连接”在一起,即MyJFrame和MySerialPort,但我不知道如何做到这一点。我这样做的原因是因为昨天我在MySerialPort类中将数据从串行端口缓冲区分配到全局字符串(finalString)时遇到问题。这个字符串应该返回到MyJFrame,在那里标签会显示它。问题是我的标签会先显示finalString 已分配给finalString,因为类在不同的线程中运行。我在论坛上发布了这个问题,并收到了使用接口连接他们线程的建议,我根据这些建议修改了代码。我在哪里使用关键字implements SerialPortListener以及如何获取该值 SerialPortListener接口代码 MyJFrame类代码 MySerialPort类代码java-为线程实现接口,java,multithreading,swing,interface,implements,Java,Multithreading,Swing,Interface,Implements,我试图使用SerialPortListener接口将两个类“连接”在一起,即MyJFrame和MySerialPort,但我不知道如何做到这一点。我这样做的原因是因为昨天我在MySerialPort类中将数据从串行端口缓冲区分配到全局字符串(finalString)时遇到问题。这个字符串应该返回到MyJFrame,在那里标签会显示它。问题是我的标签会先显示finalString 已分配给finalString,因为类在不同的线程中运行。我在论坛上发布了这个问题,并收到了使用接口连接他们线程的建议
公共类MySerialPort{
//此方法使用JSSCAPI(java简单串行连接器)
//http://code.google.com/p/java-simple-serial-connector/
专用串行端口串行端口;
private int iBaudRate=SerialPort.BAUDRATE_57600;
private int-iDataBits=SerialPort.DATABITS_8;
private int iStopBits=SerialPort.stoppbits_1;
private int iParity=SerialPort.PARITY\u NONE;
私有字符串portName=“”;
//私有字符串finalString=“”;
//私有StringBuilder sbBuffer=新StringBuilder();
private List portListeners=new ArrayList();
public void addMyPortListener(SerialPortListener侦听器){
添加(侦听器);
}
公共void removeMyPortListener(SerialPortListener侦听器){
删除(侦听器);
}
public void getFirmwareVersion(){
sendPortCommand(“\r\n”);
}
//公共字符串returnFinalString(){
//返回最后一环;
// }
public void getPortName(){
字符串[]端口=SerialPortList.getPortNames();
端口名=端口[0];
}
public void openPort(){
serialPort=新的serialPort(端口名);
试一试{
if(serialPort.openPort()){
if(serialPort.setParams(iBaudRate、iDataBits、iStopBits、iParity)){
serialPort.addEventListener(新读卡器(),serialPort.MASK\u RXCHAR
|SerialPort.MASK_RXFLAG
|SerialPort.MASK\u CTS
|SerialPort.MASK\u DSR
|串行端口掩码(RSD);
}否则{
//错误消息-无法设置所选端口参数!
serialPort.closePort();
}
}否则{
//错误消息-无法打开端口!
}
}catch(SerialPortException | HeadlessException ex){
//错误消息-无法打开端口!-不执行任何操作
}
}
私有void sendPortCommand(字符串sSendPortCommand){
if(sSendPortCommand.length()>0){
试一试{
serialPort.writeBytes(sSendPortCommand.getBytes());
}捕获(例外情况除外){
//错误消息-发送数据时出错!
}
}
}
私有类读取器实现SerialPortEventListener{
私有字符串sBuffer=“”;
@凌驾
public void serialEvent(SerialPortEvent spe){
if(spe.isRXCHAR()| | spe.isRXFLAG()){
if(spe.getEventValue()>0){
试一试{
//从缓冲区读取字符
byte[]bBuffer=serialPort.readBytes(spe.getEventValue());
sBuffer=新字符串(bBuffer);
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
for(SerialPortListenerInterface listener:portListeners){
listener.StringRevievedFromSerialPort(sBuffer);
}
}
});
//下面是我在建议使用invokeLater而不是invokeAndWait之前的代码
//
//sbBuffer.setLength(0);
//
//SwingUtilities.invokeAndWait(
//新的Runnable(){
//
//@覆盖
//公开募捐{
//sbBuffer.append(sBuffer);
// }
// });
//
//finalString=新字符串(sbBuffer);
}捕获(例外情况除外){
}
}
}
}
}
}
以下是一些可以添加到initSerialPorts()
方法中的代码,它将打开一个对话框,显示从串行端口接收的文本:
msp.addMyPortListener(new SerialPortListener() {
@Override
public void stringReveivedFromSerialPort(String s) {
JOptionPane.showMessageDialog(MyJFrame.this, s);
}
});
它创建了一个匿名的
SerialPortListener
实例,该实例将显示一个包含所接收文本的对话框作为消息,并将其添加到您的MySerialPort msp
实例中。我相信您希望您的MyJFrame
类实现SerialPortListener
:
public class MyJFrame extends JFrame implements SerialPortListener {
/* blah */
@Override
public void stringReveivedFromSerialPort(String s) {
lblFirmwareVersion.setText(s);
}
/* blah */
}
关于上一个问题:非常感谢。这几乎是我想要的方式。由于接收到的字符串需要追加以获得完整的消息,因此我仍然需要使用您的示例找出如何追加。
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) {
}
}
}
}
}
}
msp.addMyPortListener(new SerialPortListener() {
@Override
public void stringReveivedFromSerialPort(String s) {
JOptionPane.showMessageDialog(MyJFrame.this, s);
}
});
public class MyJFrame extends JFrame implements SerialPortListener {
/* blah */
@Override
public void stringReveivedFromSerialPort(String s) {
lblFirmwareVersion.setText(s);
}
/* blah */
}