您的代码违反了 Swing 线程规则。它可能正在尝试在 Swing 事件线程上运行监听代码(我们无法根据您发布的 sn-p 判断),但它肯定会尝试以错误的方式更新文本字段。相反,我建议您使用 SwingWorker 在后台线程中侦听端口,特别是使用发布/处理方法对的 SwingWorker<Void, String> 将文本发送到 JTextArea。或者,如果您需要在 GUI 的多个位置使用更复杂的信息更新 GUI,则可以通过将 PropertyChangeListener 附加到 SwingWorker 来执行此操作,这将通知任何侦听器(GUI)有关工作人员状态的更改。
更多信息,请查看Lesson: Concurrency in Swing
您的代码可能看起来像这样:
class MyWorker extends SwingWorker<Void, Void> {
// properties to listen for changes to:
public static final String LISTEN_STATE = "listen state";
public static final String CURRENT_PORT_ID = "current port id";
public static final String DATA_FEED = "data feed";
private String listenState = "None";
private String dataFeed = "";
private String currentPortId = "";
@Override
protected Void doInBackground() throws Exception {
while (true) {
if (Serial.currPortId != (null)) {
// change properties when data comes in
String currPortId = Serial.currPortId.getName();
setListenState(currPortId);
setCurrentPortId(currPortId);
setDataFeed(ImportMenu.serialImport.datafeed);
} else {
setListenState("None");
break; // ??
}
}
return null;
}
public String getListenState() {
return listenState;
}
public void setListenState(String listenState) {
// set the prop change parameters
String oldValue = this.listenState;
String newValue = listenState;
// update the propertie's state
this.listenState = listenState;
// notify listeners of the change
firePropertyChange(LISTEN_STATE, oldValue, newValue);
}
public String getDataFeed() {
return dataFeed;
}
public void setDataFeed(String dataFeed) {
// same rationale as for the other setter method
String oldValue = this.dataFeed;
String newValue = dataFeed;
this.dataFeed = dataFeed;
firePropertyChange(DATA_FEED, oldValue, newValue);
}
public String getCurrentPortId() {
return currentPortId;
}
public void setCurrentPortId(String currentPortId) {
// same rationale as for the other setter method
String oldValue = this.currentPortId;
String newValue = currentPortId;
this.currentPortId = currentPortId;
firePropertyChange(CURRENT_PORT_ID, oldValue, newValue);
}
}
然后您可以附加一个响应更改的侦听器,然后更新 GUI 中的显示
private class MyWorkerListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
switch (evt.getPropertyName()) {
case MyWorker.LISTEN_STATE:
String listenState = evt.getNewValue().toString();
// show in text field
break;
case MyWorker.CURRENT_PORT_ID:
String currentPortId = evt.getNewValue().toString();
// use this to decide which tab to change to
break;
case MyWorker.DATA_FEED:
String dataFeed = evt.getNewValue().toString();
// show where needed
break;
default:
break;
}
}
}
你会在 gui 中像这样连接它:
MyWorker worker = new MyWorker();
worker.addPropertyChangeListener(new MyWorkerListener());
worker.execute();
您还想向 SwingWorker 添加另一个 PropertyChangeListener 以侦听 SwingWorker.StateValue.DONE newValue,当它发生时,在 worker 上调用 get() 以捕获和处理任何异常