java - 实现线程的接口

时间:2012-03-01 17:47:01

标签: java multithreading swing interface implements

我正在尝试使用接口SerialPortListener将两个类“连接”在一起,MyJFrame和MySerialPort,但我对如何做到这一点毫无头绪。我这样做的原因是因为昨天我在MySerialPort类中将数据从串行端口缓冲区分配给全局String(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) {
                    }

                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

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

public class MyJFrame extends JFrame implements SerialPortListener {
  /* blah */
  @Override
  public void stringReveivedFromSerialPort(String s) {
    lblFirmwareVersion.setText(s);
  }
  /* blah */
}