Java - реализовать интерфейсы для потоков - PullRequest
0 голосов
/ 01 марта 2012

Я пытаюсь «соединить» два класса, MyJFrame и MySerialPort, используя интерфейс SerialPortListener, но я не знаю, как это сделать.Причина, по которой я это делаю, заключается в том, что вчера у меня возникла проблема с назначением данных из буфера последовательного порта для глобальной строки (finalString) в классе MySerialPort.Эта строка должна быть возвращена в 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 ]

1 голос
/ 01 марта 2012

Я полагаю, что вы хотите, чтобы ваш MyJFrame класс реализовал SerialPortListener:

public class MyJFrame extends JFrame implements SerialPortListener {
  /* blah */
  @Override
  public void stringReveivedFromSerialPort(String s) {
    lblFirmwareVersion.setText(s);
  }
  /* blah */
}
1 голос
/ 01 марта 2012

Вот некоторый код, который вы можете добавить к своему методу initSerialPorts(), и который откроет диалоговое окно, отображающее текст, полученный из последовательного порта:

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

Создает анонимный экземпляр SerialPortListener, который отображает диалоговое окно, содержащее полученный текст в виде сообщения, и добавляет его в ваш экземпляр MySerialPort msp.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...