串行通信错误:IllegalStateException& IOException异常

时间:2017-04-21 18:11:10

标签: java netbeans javafx

我有一个程序连接到USB设备,USB设备是消费产品,使用他们的软件并使用PuttY工作正常,它是一个使用字符串的相当简单的串行通信。 (根据他们的文件)。

我的部分代码存在问题,特别是在尝试使用读取字符串执行某些操作时,只需显示它 我会尽可能清楚地了解正在发生的事情:

  1. 首先,软件扫描可用的COM端口(这有效)和 填充列表
  2. 其次,用户选择一个COM端口并连接到它(这可以工作),打开COM端口,并初始化一个监听器和一个I / O 流
  3. 第三,有一个事件监听器不断更新用户可见的日志,数据正在接收(这可以正常工作 孔)
  4. 无论其!有一个按钮开始执行测试,此测试启用布尔" testinprogress"这使得监听器在数据可用上执行不同的任务,除了显示它的读数之外。

    以下是eventlistener的代码:

    @Override
    public void serialEvent(SerialPortEvent evt) {
        BufferedReader reader = null;
    
        if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
        {
            if (testProgress == true)
            {
                 try
                {
                    reader = new BufferedReader(new InputStreamReader(input));
                    TemperatureParser parser = new TemperatureParser();
                    TemperatureReading reading;
                    output.flush();
                    reading = parser.parse(reader.readLine());
                    readings.add(reading);
                    textLog.appendText(reader.readLine() + "\n");
                }
                catch (Exception e)
                {
                statusLabel.setText("@serialEvent.IF Failed to read data. (" + e.toString() + ")");
                System.out.println("@SerialEvent.IF Failed to read data. (" + e.toString() + ")");
                }
            }
            else
            {
                try
            {
                reader = new BufferedReader(new InputStreamReader(input));
                    fullLine = reader.readLine();
                    textLog.appendText(fullLine + "\n");
            }
            catch (Exception e)
            {
                statusLabel.setText("@serialEvent.ELSE Failed to read data. (" + e.toString() + ")");
                System.out.println("@SerialEvent.ELSE Failed to read data. (" + e.toString() + ")");
            }
            }
        }
    }
    

    现在,问题是,如果我注释掉以下几行,那么read-then-display的工作正常:

                reading = parser.parse(reader.readLine());
                readings.add(reading);
    

    这两行与为该项目创建的特殊类相关(Credit to James_D):

    //SPECIAL CLASSES NEEDED
        public class TemperatureReading {
            private final double[] values;
            private final LocalDateTime timeStamp;
    
            public TemperatureReading(LocalDateTime timeStamp, double... values) {
                this.timeStamp = timeStamp;
                this.values = new double[values.length];
                System.arraycopy(values, 0, this.values, 0, values.length);
            }
    
            public TemperatureReading(double... values){
                this(LocalDateTime.now(), values);
            }
    
            public double getValue(int channel) {
                return values[channel];
            }
    
            public int getNumberOfChannels() {
                return values.length;
            }
    
            public LocalDateTime getTimestamp(){
                return timeStamp;
            }
    
            public boolean noneExceed(double max) {
                return DoubleStream.of(values).allMatch(v -> v <= max);
            }
        }
    
        public class TemperatureParser {
            public TemperatureReading parse (String text) {
                return new TemperatureReading(Stream.of(text.split(SPLIT)).mapToDouble(Double::parseDouble).toArray());
            }
        }
    

    最后,当我们没有注意到这些线路时出现的错误

    OLD ERROR MESSAGES. SEE EDIT
    

    另一个可能与此有关的注释是,有时缓冲区读取器不读取整行,这是我得到的一些输出(这些行被注释掉,没有错误)

    Setting testInProgress to true 
     24.552  24.505  24.515  24.413  
    24.457  24.435  24.354  24.433  24.510  24.553  24.506  24.515  24.413  
    24.458  24.435  24.355  24.433  24.511  24.554  24.507  24.515  24.413  
    24.458  24.436  24.355  24.433  24.511  24.554  24.507  24.515  24.413  
    Test stopped by user! 
    OK
    

    现在你看,在testInProgress设置为true后,第一行是INCOMPLETE(它应该是9个读数)。我只得到前一行的部分后半部分,我不知道这可能是原因,但即便如此,他们仍然可以解析。

    修改
    我修改了代码如下:

    public class TemperatureParser {
        public TemperatureReading parse (String text) {
            System.out.println("String received: " + text);
            if (text != null && text.length() > 0)
            {
            return new TemperatureReading(Stream.of(text.split(SPLIT)).mapToDouble(Double::parseDouble).toArray());
            }
            else
            {
            System.out.println("Null reading");
            return null;
            }
        }
    }
    

    这至少让我知道解析器正在获得一个完整的字符串行并且它正在工作。还修改了eventlistener,如下所示:(添加了72个字符的检查,这是9个读数)

    if (testProgress == true)
                {
                     try
                    {
                        reader = new BufferedReader(new InputStreamReader(input));
                        fullLine = reader.readLine();
                        if (fullLine.length() == 72)
                        {
                            textLog.appendText(fullLine + "\n");
                            reading = parser.parse(fullLine);
                            readings.add(reading);
    
                        }
    
                    }
                    catch (Exception e)
                    {
                    statusLabel.setText("@serialEvent.IF Failed to read data. (" + e.toString() + ")");
                    System.out.println("@SerialEvent.IF Failed to read data. (" + e.toString() + ")");
                    }
    

    使用这个新代码我得到的错误更少,所以我认为我正在走上正轨:

    testProgress is True
    String received: 25.360  25.371  25.254  25.342  25.545  25.609  25.501  25.527  25.444  
    Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
        at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
        at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
        at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
        at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
        at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
        at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
        at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
        at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
        at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
        at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
        at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
        at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
        at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
        at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
        at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
        at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
        at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
        at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
        at javafx.scene.control.Labeled.setText(Labeled.java:145)
        at at.qcresponsetime.FXMLDocumentController.serialEvent(FXMLDocumentController.java:602)
        at gnu.io.RXTXPort.sendEvent(RXTXPort.java:772)
        at gnu.io.RXTXPort.eventLoop(Native Method)
        at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1641)
    String received: 25.362  25.371  25.255  25.346  25.547  25.608  25.498  25.527  25.446  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    String received: 25.363  25.371  25.256  25.350  25.548  25.607  25.495  25.526  25.448  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    String received: 25.365  25.371  25.257  25.355  25.550  25.607  25.493  25.526  25.450  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    String received: 25.365  25.371  25.258  25.355  25.550  25.607  25.493  25.526  25.450  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    String received: 25.365  25.372  25.258  25.355  25.550  25.607  25.493  25.527  25.450  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    String received: 25.365  25.372  25.258  25.355  25.550  25.607  25.494  25.527  25.450  
    @SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    testProgress is False
    Stop Button pressed!
    

1 个答案:

答案 0 :(得分:0)

您收到NumberFormatException。这意味着您正在尝试将字符串解析为整数,并且在此过程中会出现某种错误。我最好的猜测是变量fullLine给你一个空字符串,所以尝试添加if周围:

reading = parser.parse(fullLine);
readings.add(reading);

检查fullLine是否为空,除了检查它的长度。 据我所知,错误告诉你字符串是空的,所以只需在代码的不同位置测试打印该变量。