我正在开发邮箱,我希望客户端自动检查是否有新电子邮件。我通过使用一个循环直到关闭客户端的线程来完成此操作,如果发现列表中的当前电子邮件数量与服务器上的文件数量不同,它将重新加载数据并添加新电子邮件。它有效,但是每次列表上有更新时,都会出现此异常:
Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
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.ListCellSkin.handleControlPropertyChanged(ListCellSkin.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 mailbox.ListController$1.updateItem(ListController.java:56)
at mailbox.ListController$1.updateItem(ListController.java:49)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
at javafx.scene.control.ListCell.access$300(ListCell.java:72)
at javafx.scene.control.ListCell$2.changed(ListCell.java:185)
at javafx.scene.control.ListCell$2.changed(ListCell.java:175)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.control.ListView.setItems(ListView.java:390)
at mailbox.ListController$2.run(ListController.java:71)
这是我的ListView Controller代码:
public class ListController {
@FXML
private ListView<Email> listView;
private DataModel model;
private int NoE;
public void initModel(DataModel model) throws IOException, ClassNotFoundException, ParseException {
if (this.model != null) {
throw new IllegalStateException("Model can only be initialized once");
}
this.model = model;
model.loadData();
listView.setItems(model.getEmailList());
listView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection)
-> model.setCurrentEmail(newSelection));
model.currentEmailProperty().addListener((obs, oldEmail, newEmail) -> {
if (newEmail == null) {
listView.getSelectionModel().clearSelection();
} else {
listView.getSelectionModel().select(newEmail);
}
});
listView.setCellFactory(lv -> new ListCell<Email>() {
@Override
public void updateItem(Email mail, boolean empty) {
super.updateItem(mail, empty);
if (empty) {
setText(null);
} else if (mail != null) {
setText(mail.getMittente());
}
}
});
NoE = model.getNumberOfEmail();
new Thread() {
@Override
public void run() {
while (true) {
try {
int current = model.askNumbOfEmail();
if (NoE != current) {
NoE = current;
model.reLoadData();
listView.setItems(model.getEmailList());
}
} catch (IOException ex) {
Thread.currentThread().interrupt();
return;
} catch (ParseException ex) {
System.out.println("ParseException ERROR!");
}
}
}
}.start();
}
}
答案 0 :(得分:2)
您需要输入这一行
listView.setItems(model.getEmailList());
Platform.runLater(() -> listView.setItems(model.getEmailList()));