我正在制作一个使用串行通信的应用程序。在该类的SerialEvent
方法中,我正在等待来自COM端口的输入,然后我想将其传递给.fxml
屏幕的控制器类。
输入将始终为8个字节,并且它在该线程内正常工作(我读取输入并将其打印到输出,我看到String
是正确的)。但是,当我试图实时传递它时#34;对于控制器类,我有一个问题。
如果我直接传递它,它会收到它,但我以后不能调用任何东西(不是FX应用程序线程异常),我知道我不能这样做,我需要使用Platform.runLater
或similair解决方案,但如果我这样使用它,我的控制器类永远不会收到该输入,我试图更新的textField
保持空白。
我会在这里复制部分代码,我希望有人能告诉我我做错了什么。
另一类的SERIALEVENT方法
@Override
public void serialEvent(SerialPortEvent spe) {
if (spe.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
byte singleData = (byte) input.read();
logText = new String(new byte[]{singleData});
bytes.add(logText);
if(bytes.size() == 8) {
for (int i = 0; i < bytes.size(); i++) {
inputText += bytes.get(i);
}
if(inputText.length() == 8) {
Platform.runLater(new Runnable() {
@Override
public void run() {
controller.getInputString(inputText);
}
});
}
bytes.clear();
inputText = "";
}
} catch (Exception e) {
logText = "Failed to read data. (" + e.toString() + ")";
controller.getInputString(logText);
}
}
}
控制器类的GETINPUT方法
@Override
public void getInputString(String input) {
firstSerialNumberField.setText(input);
}
以这种方式使用时,我的firstSerialNumberField
永远不会得到那个输入。
--- --- EDIT
SERIALPORTLISTENER CLASS的SETCONTROLLER方法
public void setController(SerialController controller) {
this.controller = controller;
}
屏幕处理程序类中的初始化屏幕
serialCommunication = new SerialCommunication(this);
loader = new FXMLLoader();
loader.setLocation(getClass().getResource(path));
pane = loader.load(getClass().getResource(path).openStream());
serialController = (SerialController) loader.getController();
serialController.setScreenHandler(this);
serialController.setSerialCommunication(serialCommunication);
serialCommunication.setController(serialController);
parent = loader.getRoot();
stage = new Stage();
stage.setScene(new Scene(parent));
stage.setTitle(title);
stage.setResizable(false);
stage.sizeToScene();
stage.centerOnScreen();
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
答案 0 :(得分:0)
您正在将inputText
的引用传递给控制器中的(不恰当命名的)getInputText()
方法。 inputText
可能是实现端口侦听器的类中的一个字段。但是,只要您传递它,然后将其设置回空字符串:
if(inputText.length() == 8) {
Platform.runLater(new Runnable() {
@Override
public void run() {
controller.getInputString(inputText);
}
});
}
bytes.clear();
inputText = "";
由于正在从多个线程访问inputText
,因此无法保证将发生的事情是:首先执行controller.getInputText(inputText)
,还是首先执行inputText = "";
。因此,您最终可能会将文本字段设置为空字符串。
我认为你打算做的是:
if(inputText.length() == 8) {
final String numberFieldText = inputText ;
Platform.runLater(new Runnable() {
@Override
public void run() {
controller.getInputString(numberFieldText);
}
});
}
或更简洁:
if(inputText.length() == 8) {
final String numberFieldText = inputText ;
Platform.runLater(() -> controller.getInputString(numberFieldText));
}