코드가 스윙 스레딩 규칙을 위반합니다. Swing 이벤트 스레드에서 청취 코드를 실행하려고 시도했을 수 있습니다 (게시 한 스 니펫을 기반으로 말할 수는 없지만) 스레드의 텍스트 필드를 잘못 업데이트하려고합니다. 대신, SwingWorker를 사용하여 백그라운드 스레드의 포트를 수신하는 것이 좋습니다. 특히 SwingWorker<Void, String>
게시/처리 메소드 쌍을 사용하여 JTextArea에 텍스트를 전송하는 것이 좋습니다. 또는 GUI의 여러 위치로 이동하는보다 복잡한 정보로 GUI를 업데이트해야하는 경우 PropertyChangeListener를 SwingWorker에 연결하여 작업자 상태에 대한 변경 사항을 리스너 (GUI)에 알립니다.
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
에 표시를 갱신 자세한 내용은
, Lesson: Concurrency in Swing
귀하의 코드는 다음과 같이 뭔가을 볼 수 있었다 체크 아웃
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.StateValue.DONE NEWVALUE을 수신하기 위해 SwingWorker의 또 다른 PropertyChangeListener를 추가 할, 그리고이 발생하면 트랩에 작업자 get()
를 호출하고 예외를 처리 할 것
나 '
이걸 보게, 고마워! 청취 코드는 "직렬"을 통해 여기에서 호출되는 다른 클래스에서 실행됩니다. 업데이트하는 경우에 불과합니다. 직렬 포트에 대한 많은 경험이 없기 때문에 모든 것을 배울 수 있습니다. –
@JosephOliver :하지만 백그라운드 스레드에서 청취 코드를 실행하고 있습니까? 그렇지 않은 경우 코드가 완전히 응답하여 완전히 응답하지 않을 것으로 예상합니다. –
@JosephOliver : 불완전한 예를 들어 답을 편집하십시오. –