2016-04-15 82 views
1

我创建了一个使用Arduino和几个组件以及JavaFX中的小型测试应用程序(代码如图所示)的电路。问题是我无法获得 COM端口(使用Windows 10)显示在组合框中,但是我可以在输出控制台(COM5上的Arduino)中看到它们。当我在intellij运行代码检查 时,我得到 “作为原始类型'javafx.beans.value.ObservableValue'(在第92行)的成员,问题摘要 - 未检查的调用'addListener(ChangeListener?super T>)'” 这似乎有用。我认为这意味着听众不再听,但我真的不知道。JavaFX组合框不显示COM端口

代码FXML文件:

<?xml version="1.0" encoding="UTF-8"?> 

    <?import javafx.geometry.Insets?> 
    <?import javafx.scene.control.Button?> 
    <?import javafx.scene.control.ComboBox?> 
    <?import javafx.scene.control.Label?> 
    <?import javafx.scene.control.TextField?> 
    <?import javafx.scene.image.ImageView?> 
    <?import javafx.scene.layout.BorderPane?> 
    <?import javafx.scene.layout.HBox?> 
    <?import javafx.scene.layout.VBox?> 
    <?import javafx.scene.text.Font?> 

    <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="538.0" prefWidth="734.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="labrat.Controller"> 
     <top> 
      <VBox prefHeight="148.0" prefWidth="723.0" style="-fx-background-color: #1f3641;" BorderPane.alignment="CENTER"> 
      <children> 
       <HBox prefHeight="25.0" prefWidth="723.0" style="-fx-background-color: #d2d4df;"> 
        <children> 
         <Label text="LabRat Version R" textFill="#5b5b5b"> 
         <font> 
          <Font size="14.0" /> 
         </font> 
         <HBox.margin> 
          <Insets bottom="5.0" left="3.0" right="3.0" top="3.0" /> 
         </HBox.margin> 
         </Label> 
        </children> 
       </HBox> 
       <HBox> 
        <children> 
         <Button fx:id="changeText" mnemonicParsing="false" onAction="#setChangeText" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #ffffff;" text="Change text" textFill="#4a4a4a"> 
         <HBox.margin> 
          <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> 
         </HBox.margin> 
         <font> 
          <Font size="16.0" /> 
         </font> 
         </Button> 
         <Label fx:id="dynamicText" text="Default Text" textFill="WHITE"> 
         <font> 
          <Font size="24.0" /> 
         </font> 
         <HBox.margin> 
          <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> 
         </HBox.margin> 
         </Label> 
        </children> 
        <VBox.margin> 
         <Insets top="10.0" /> 
        </VBox.margin> 
       </HBox> 
       <HBox layoutX="10.0" layoutY="10.0"> 
        <children> 
         <Button fx:id="addElement" mnemonicParsing="false" onAction="#setAddElement" prefHeight="50.0" prefWidth="200.0" style="-fx-background-color: #ffffff;" text="Add element" textFill="#4a4a4a"> 
         <HBox.margin> 
          <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> 
         </HBox.margin> 
         <font> 
          <Font size="16.0" /> 
         </font> 
         </Button> 
         <TextField fx:id="typeToAdd" prefHeight="25.0" prefWidth="231.0" promptText="type to add to combobox"> 
         <HBox.margin> 
          <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> 
         </HBox.margin> 
         </TextField> 
         <ComboBox fx:id="element" prefHeight="25.0" prefWidth="238.0" promptText="select element" style="-fx-background-color: #ffcc99;"> 
         <HBox.margin> 
          <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> 
         </HBox.margin> 
         </ComboBox> 
        </children> 
        <VBox.margin> 
         <Insets top="10.0" /> 
        </VBox.margin> 
       </HBox> 
      </children> 
      </VBox> 
     </top> 
     <center> 
      <VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #1f3641;" BorderPane.alignment="CENTER"> 
      <children> 
       <HBox VBox.vgrow="ALWAYS"> 
        <children> 
         <ImageView fx:id="imgVw" fitHeight="319.0" fitWidth="421.0" pickOnBounds="true" preserveRatio="true" /> 
         <VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #cc0000;" HBox.hgrow="ALWAYS"> 
         <children> 
          <Label fx:id="labelValue" text="Label Value" textFill="WHITE"> 
           <font> 
            <Font size="18.0" /> 
           </font> 
           <VBox.margin> 
            <Insets bottom="20.0" /> 
           </VBox.margin> 
          </Label> 
          <ComboBox fx:id="comboBoxPorts" prefHeight="25.0" prefWidth="277.0" promptText="COM PORTS" style="-fx-background-color: #bdc3c7;" styleClass="comboBox" stylesheets="@testSS.css" /> 
         </children> 
         <padding> 
          <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> 
         </padding> 
         </VBox> 
        </children> 
       </HBox> 
      </children> 
      </VBox> 
     </center> 
     <bottom> 
      <HBox prefHeight="66.0" prefWidth="723.0" style="-fx-background-color: #222222;" BorderPane.alignment="CENTER"> 
      <children> 
       <Button fx:id="nextScene" mnemonicParsing="false" onAction="#setNextScene" prefHeight="40.0" prefWidth="150.0" style="-fx-background-color: #d2d4df;" text="Next Scene"> 
        <HBox.margin> 
         <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
        </HBox.margin> 
        <font> 
         <Font size="16.0" /> 
        </font> 
       </Button> 
       <Button fx:id="exit" mnemonicParsing="false" prefHeight="40.0" prefWidth="150.0" style="-fx-background-color: #ff0000;" text="Exit Lab" textFill="WHITE"> 
        <HBox.margin> 
         <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
        </HBox.margin> 
        <font> 
         <Font size="16.0" /> 
        </font> 
       </Button> 
       <Button fx:id="version" layoutX="190.0" layoutY="20.0" mnemonicParsing="false" onAction="#setVersion" prefHeight="40.0" prefWidth="150.0" style="-fx-background-color: #ffffff;" text="Alert Version"> 
        <font> 
         <Font size="16.0" /> 
        </font> 
        <HBox.margin> 
         <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
        </HBox.margin> 
       </Button> 
       <Button fx:id="showTheCar" layoutX="360.0" layoutY="20.0" mnemonicParsing="false" onAction="#setShowTheCar" prefHeight="40.0" prefWidth="150.0" style="-fx-background-color: #ffffff;" text="Show the car!"> 
        <font> 
         <Font size="16.0" /> 
        </font> 
        <HBox.margin> 
         <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
        </HBox.margin> 
       </Button> 
      </children> 
      </HBox> 
     </bottom> 
    </BorderPane> 

代码JavaFX类:

package labrat; 

    import javafx.application.Application; 
    import javafx.application.Platform; 
    import javafx.beans.value.ChangeListener; 
    import javafx.beans.value.ObservableValue; 
    import javafx.collections.FXCollections; 
    import javafx.collections.ObservableList; 
    import javafx.event.ActionEvent; 
    import javafx.fxml.FXML; 
    import javafx.fxml.FXMLLoader; 
    import javafx.scene.Node; 
    import javafx.scene.Parent; 
    import javafx.scene.Scene; 
    import javafx.scene.control.*; 
    import javafx.scene.image.Image; 
    import javafx.scene.image.ImageView; 
    import javafx.stage.Stage; 
    import jssc.SerialPort; 
    import jssc.SerialPortEvent; 
    import jssc.SerialPortException; 
    import jssc.SerialPortList; 

    import java.io.IOException; 

    public class Controller extends Application 
    { 
     @FXML 
     Button changeText; 
     @FXML 
     Button showTheCar; 
     @FXML 
     Label dynamicText; 
     @FXML 
     Button addElement; 
     @FXML 
     TextField typeToAdd; 
     @FXML 
     ComboBox<String> element; 
     @FXML 
     Button nextScene; 
     @FXML 
     Button exit; 
     @FXML 
     Button version; 
     @FXML 
     ImageView imgVw; 
     @FXML 
     private Image img; 


     // for serial com 
     SerialPort arduinoPort = null; 

     ObservableList<String> portList; 

     @FXML 
     private Label labelValue; 
     @FXML 
     ComboBox comboBoxPorts; 



     @Override 
     public void start(Stage primaryStage) 
     { 
      Parent rootParent = null; 
      try 
      { 
       rootParent = FXMLLoader.load(getClass().getResource("firstScene.fxml")); 
       primaryStage.setTitle("Test Lab version 3200"); 
       primaryStage.setScene(new Scene(rootParent, 1100, 600)); 
       primaryStage.show(); 
       System.out.println("First Stage now showing"); 
      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 

      labelValue = new Label(); 
      detectPort(); 
      comboBoxPorts = new ComboBox(portList); 
      comboBoxPorts.valueProperty().addListener(new ChangeListener<String>() { 

       @Override 
       public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
        System.out.println("\nJust making sure this was executed!"); 
        disconnectArduino(); 
        connectArduino(newValue); 
       } 
      }); 
      /* 
      comboBoxPorts.getItems().addAll(portList); 
      if(comboBoxPorts.getItems().addAll(portList)) 
      { 
       System.out.println("\nAdded port-list(from observable list) to the CB!"); 
      } 

      if(!(comboBoxPorts.getItems().addAll(portList))) 
      { 
       System.out.println("\nPort-list not added to CB!"); 
      } 
      */ 

     } 

     @Override 
     public void stop() throws Exception 
     { 
      disconnectArduino(); 
      super.stop(); 
     } 

     // port detector method 
     private void detectPort(){ 

      System.out.println("\n1/3 Now detecting port..."); 

      portList = FXCollections.observableArrayList(); 

      String[] serialPortNames = SerialPortList.getPortNames(); 
      for(String name: serialPortNames){ 

       System.out.println("\nDetected Port: "); 
       System.out.println(name); 
       portList.add(name); 
      } 
     } 

     // connect the Arduino 
     public boolean connectArduino(String port) 
     { 
      System.out.println("\n2/3 Connect Arduino now running..."); 

      boolean success = false; 
      SerialPort serialPort = new SerialPort(port); 
      try { 
       serialPort.openPort(); 
       serialPort.setParams(
         SerialPort.BAUDRATE_9600, 
         SerialPort.DATABITS_8, 
         SerialPort.STOPBITS_1, 
         SerialPort.PARITY_NONE); 
       serialPort.setEventsMask(SerialPort.MASK_RXCHAR); 
       serialPort.addEventListener((SerialPortEvent serialPortEvent) -> { 
        if(serialPortEvent.isRXCHAR()){ 
         try { 
          String st = serialPort.readString(serialPortEvent 
            .getEventValue()); 

          System.out.println("\nSPE Listener: "); 
          System.out.println(st); 

          //Update label in ui thread 
          Platform.runLater(() -> { 
           System.out.println("\nAttempted to update label in ui thread"); 
           labelValue.setText(st); 
          }); 

         } catch (SerialPortException ex) { 
          ex.printStackTrace(); 
         } 
        } 
       }); 

       arduinoPort = serialPort; 
       success = true; 
      } catch (SerialPortException ex) { 
       ex.printStackTrace(); 
       System.out.println("SerialPortException: " + ex.toString()); 
      } 

      return success; 
     } 

     // disconnect the Arduino 
     public void disconnectArduino() 
     { 
      System.out.println("\n3/3 Now disconnecting Arduino..."); 

      if(arduinoPort != null) 
      { 
       try 
       { 
        arduinoPort.removeEventListener(); 

        if(arduinoPort.isOpened()) 
        { 
         arduinoPort.closePort(); 
        } 
       } 
       catch (SerialPortException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     } 

     @FXML 
     public void setChangeText() 
     { 
      dynamicText.setText("Text changed successfully!"); 
     } 

     @FXML 
     public void setShowTheCar() 
     { 
      img = new Image("labrat/images/megane.jpg"); 
      imgVw.setImage(img); 
      imgVw.isPreserveRatio(); 
     } 

     @FXML 
     public void setVersion() 
     { 
      Alert alert = new Alert(Alert.AlertType.INFORMATION); 
      alert.setTitle("LabRat Version"); 
      alert.setContentText("Version after the previous one! v0.001"); 
      alert.showAndWait(); 
     } 

     @FXML 
     public void setNextScene(ActionEvent ev) 
     { 
      try 
      { 
       Parent secondParent = FXMLLoader.load(getClass().getResource("secondScene.fxml")); 
       Scene secondScene = new Scene(secondParent); 
       Stage ourStage = (Stage) ((Node) ev.getSource()).getScene().getWindow(); 
       ourStage.setTitle("Test Lab Page II"); 
       ourStage.setScene(secondScene); 
       ourStage.show(); 
      } 

      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 

     @FXML 
     public void setAddElement() 
     { 
      String bufferText = typeToAdd.getText(); 
      element.getItems().addAll(bufferText); 
     } 
    } 

控制台输出时,将显示场景高达:

"C:\Program Files\Java\jdk1.8.0_73\bin\java" (cut this short to minimize length) 
    First Stage now showing 

    1/3 Now detecting port... 

    Detected Port: 
    COM5 

我怎样才能获得组合框显示端口?基于

  package labrat; 

    import javafx.application.Application; 
    import javafx.application.Platform; 
    import javafx.beans.value.ChangeListener; 
    import javafx.beans.value.ObservableValue; 
    import javafx.collections.FXCollections; 
    import javafx.collections.ObservableList; 
    import javafx.event.ActionEvent; 
    import javafx.fxml.FXML; 
    import javafx.fxml.FXMLLoader; 
    import javafx.fxml.Initializable; 
    import javafx.scene.Node; 
    import javafx.scene.Parent; 
    import javafx.scene.Scene; 
    import javafx.scene.control.*; 
    import javafx.scene.image.Image; 
    import javafx.scene.image.ImageView; 
    import javafx.stage.Stage; 
    import jssc.SerialPort; 
    import jssc.SerialPortEvent; 
    import jssc.SerialPortException; 
    import jssc.SerialPortList; 

    import java.io.IOException; 
    import java.net.URL; 
    import java.util.ResourceBundle; 

    public class Controller implements Initializable 
    { 
     @FXML 
     Button changeText; 
     @FXML 
     Button showTheCar; 
     @FXML 
     Label dynamicText; 
     @FXML 
     Button addElement; 
     @FXML 
     TextField typeToAdd; 
     @FXML 
     ComboBox<String> element; 
     @FXML 
     Button nextScene; 
     @FXML 
     Button exit; 
     @FXML 
     Button version; 
     @FXML 
     ImageView imgVw; 
     @FXML 
     private Image img; 


     // for serial com 
     SerialPort arduinoPort = null; 

     ObservableList<String> portList; 

     @FXML 
     private Label labelValue; 
     @FXML 
     ComboBox comboBoxPorts; 


     @Override 
     public void initialize(URL location, ResourceBundle resources) 
     { 
      detectPort(); 
     } 

     // port detector method 
     private void detectPort(){ 

      System.out.println("\n1/3 Now detecting port..."); 

      portList = FXCollections.observableArrayList(); 

      String[] serialPortNames = SerialPortList.getPortNames(); 
      for(String name: serialPortNames){ 

       System.out.println("\nDetected Port: "); 
       System.out.println(name); 
       portList.add(name); 
      } 

      // No need to create a new combo instance 
      // No need to add a change listener to refresh ports 
      comboBoxPorts.setItems(portList); 
      comboBoxPorts.valueProperty().addListener(new ChangeListener<String>() { 
       @Override 
       public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) 
       { 
        System.out.println("\nChangeListener executed!"); 
        disconnectArduino(); 
        connectArduino(newValue); 
        System.out.println("\nOld Value was: " + oldValue); 
        System.out.println("\nNew Value is: " + newValue); 
        labelValue.setText(newValue); 
       } 
      }); 
     } 

     // connect the Arduino 
     public boolean connectArduino(String port) 
     { 
      System.out.println("\n2/3 Connect Arduino now running..."); 

      boolean success = false; 
      SerialPort serialPort = new SerialPort(port); 
      try { 
       serialPort.openPort(); 
       serialPort.setParams(
         SerialPort.BAUDRATE_9600, 
         SerialPort.DATABITS_8, 
         SerialPort.STOPBITS_1, 
         SerialPort.PARITY_NONE); 
       serialPort.setEventsMask(SerialPort.MASK_RXCHAR); 
       serialPort.addEventListener((SerialPortEvent serialPortEvent) -> { 
        if(serialPortEvent.isRXCHAR()){ 
         try { 
          String st = serialPort.readString(serialPortEvent 
            .getEventValue()); 

          System.out.println("\nSPE Listener: "); 
          System.out.println(st); 

          //Update label in ui thread 
          Platform.runLater(() -> { 
           System.out.println("\nAttempted to update label in ui thread"); 
           labelValue.setText(st); 
          }); 

         } catch (SerialPortException ex) { 
          ex.printStackTrace(); 
         } 
        } 
       }); 

       arduinoPort = serialPort; 
       success = true; 
      } catch (SerialPortException ex) { 
       ex.printStackTrace(); 
       System.out.println("SerialPortException: " + ex.toString()); 
      } 

      return success; 
     } 

     // disconnect the Arduino 
     public void disconnectArduino() 
     { 
      System.out.println("\n3/3 Now disconnecting Arduino..."); 

      if(arduinoPort != null) 
      { 
       try 
       { 
        arduinoPort.removeEventListener(); 

        if(arduinoPort.isOpened()) 
        { 
         arduinoPort.closePort(); 
        } 
       } 
       catch (SerialPortException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     } 

     @FXML 
     public void setChangeText() 
     { 
      dynamicText.setText("Text changed successfully!"); 
     } 

     @FXML 
     public void setShowTheCar() 
     { 
      img = new Image("labrat/images/megane.jpg"); 
      imgVw.setImage(img); 
      imgVw.isPreserveRatio(); 
     } 

     @FXML 
     public void setVersion() 
     { 
      Alert alert = new Alert(Alert.AlertType.INFORMATION); 
      alert.setTitle("LabRat Version"); 
      alert.setContentText("Version after the previous one! v0.001"); 
      alert.showAndWait(); 
     } 

     @FXML 
     public void setNextScene(ActionEvent ev) 
     { 
      try 
      { 
       Parent secondParent = FXMLLoader.load(getClass().getResource("secondScene.fxml")); 
       Scene secondScene = new Scene(secondParent); 
       Stage ourStage = (Stage) ((Node) ev.getSource()).getScene().getWindow(); 
       ourStage.setTitle("Test Lab Page II"); 
       ourStage.setScene(secondScene); 
       ourStage.show(); 
      } 

      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 

     @FXML 
     public void setAddElement() 
     { 
      String bufferText = typeToAdd.getText(); 
      element.getItems().addAll(bufferText); 
     } 

    } 

回答

1

我不是JavaFx专家,但我认为你是混合了两个概念应用程序和控制器。如果控制器未正确初始化,JoséPereda建议的更改可能会导致NullPointerException。

我已经成功推出了一个使用你的fxml文件的小演示,并且改变你的控制器来不调用arduino。但是我已经使用了额外的课程来启动这个场景。这样@FMX元素被正确注入,组合框显示端口。

主要

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class ComboMain extends Application { 
     @Override 
     public void start(Stage primaryStage) throws Exception{ 
      Parent root = FXMLLoader.load(getClass().getResource("combo.fxml")); 
      primaryStage.setTitle("Combo"); 
      primaryStage.setScene(new Scene(root)); 
      primaryStage.show(); 
     } 

     public static void main(String[] args) { 
      launch(args); 
     } 
} 

控制器

public class ComboController implements Initializable { 
     // @FXML elements here 

     @Override 
     public void initialize(URL arg0, ResourceBundle arg1) { 
      detectPort(); // Include all the code that you need for initializing elements here 
     } 

     // port detector method 
     // Dummy method - Include arduino calls here 
     private void detectPort(){ 

      System.out.println("\n1/3 Now detecting port..."); 

      portList = FXCollections.observableArrayList(); 

      String[] serialPortNames = {"COM1", "COM2", "COM3"}; // SerialPortList.getPortNames(); 

      for(String name: serialPortNames){ 
       System.out.println("\nDetected Port: "); 
       System.out.println(name); 
       portList.add(name); 
      } 

      // No need to create a new combo instance 
      // No need to add a change listener to refresh ports 
      comboBoxPorts.setItems(portList); 
     } 

     // Arduino methods here 
    } 

正如我所说,我不是专家JavaFX的,但也许你可以将一些改变你的代码。

+1

谢谢...试一试! –

+1

@RubiRic @ Jose编辑我的控制器 - 谢谢你们。该端口现在显示在ComboBox中。如果只有我可以选择两个答案! –

+1

@tpmabb翻转硬币。头!;-P – RubioRic

1

:端口现在显示(最终代码)编辑 - 我使用JSSC插件版本2.8.0

编辑 - - 以@RubioRic和@Jose佩雷达的建议后,控制器纠正变化您的代码:

@FXML 
ComboBox comboBoxPorts; 

@Override 
public void start(Stage primaryStage) 
{ 
    ... 
    comboBoxPorts = new ComboBox(portList); 
} 

里面的start()方法所创建的comboBoxPorts的第二个实例。这是获取端口列表的那个,但是这不会被添加到场景图中。

相反,您不会向创建的场景图上的第一个实例添加任何内容,这要归功于@FXML注释。

你只需要添加列表:

@FXML 
ComboBox comboBoxPorts; 

@Override 
public void start(Stage primaryStage) 
{ 
    ... 
    comboBoxPorts.setItems(portList); 
} 

编辑

而作为@RubioRic在他的回答已表示,尽管可能像你有合并ApplicationController类内容完成后,它将不允许您从start()方法访问注入的节点,并且任何尝试调用comboBoxPorts都会抛出NPE,因为您将处理该类的两个非相关实例(一个由启动器创建,另一个通过FXMLLoader)。

通常的做法是创建一个合适的Controller类,使用initialize方法,同时从Application.start()方法加载fxml。

Controller类

@FXML 
ComboBox comboBoxPorts; 

public void initialize() { 
    ... 
    comboBoxPorts.setItems(portList); 
} 

EDIT 2

在您仍想使用原来的单一类方法的情况下,这将工作:

从取出fx:controller标签fxml文件,并将控制器设置为start()方法,参考this,这样你就可以拥有只有一个实例:

@FXML 
ComboBox comboBoxPorts; 

@Override 
public void start(Stage stage) throws Exception { 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("firstScene.fxml")); 
    loader.setController(this); 
    Parent root = loader.load(); 
    ... 
    comboBoxPorts.setItems(portList); 
} 
+0

谢谢。我试图改正,但现在我得到一个异常 - 检测端口: COM5 例外在应用程序启动方法 3/3现在断开Arduino ... 线程“主”java.lang.NoSuchMethodException异常:labrat.Controller .main([Ljava.lang.String;) \t at java.lang.Class.getMethod(Class.java:1786) \t at com.intellij.rt.execution.application.AppMain.main(AppMain.java:119 ) 过程完成,退出代码为1 –

+0

如果我在try catch块,我得到一个空指针异常-java.lang.NullPointerException \t在labrat.Controller.start(Controller.java:85把代码) –

+0

你能编辑哟你的问题与例外,提到哪些是85线? –