所以我的问题是,我有一个serilized ArrayList,并且必须在我的GUI中更新它以动态显示其在ListView中的内容。 序列化和反序列化使用DAO接口可以正常工作,但GUI不会刷新我的ListView。JavaFX,List到ObservableList到ListView
此类包含我的数据交互(主要是保存,加载...):
public class Medienverwaltung implements Serializable, IDAO{
private static final long serialVersionUID = 1L;
private List<Medium> medienliste;
public ObservableList<Medium> obList; //public for test-reasons
public Medienverwaltung(){
medienliste = new ArrayList<Medium>();
obList = FXCollections.observableArrayList(medienliste);
}
//[...]
public List<Medium> getMedienliste(){
return this.medienliste;
}
//[...]
}
这才是我的GUI实现片断:
public class HauptFenster extends Application{
private Medienverwaltung medienverwaltung;
@Override
public void start(Stage stage) throws Exception{
medienverwaltung = new Medienverwaltung();
VBox root = new VBox();
ListView<String> showliste = new ListView<String>();
MenuBar menuBar = createMenuBar(stage);
root.getChildren().add(menuBar);
root.getChildren().add(showliste);
//Make Listener and refresh the shown list!
medienverwaltung.obList.addListener(new ListChangeListener<Medium>(){
@Override
public void onChanged(ListChangeListener.Change<? extends Medium> change) {
showliste.getItems().clear();
for(Medium medium : medienverwaltung.obList){
//toString() is overwritten and works, too
showliste.getItems().add(medium.toString());
}
}
});
// this adds a Medium object to the Arraylist in Medienverwaltung
medienverwaltung.aufnehmen(new Bild("Foto12", 2017, "Zuhause"));
stage.setTitle("Medien Verwaltung");
stage.setScene(new Scene(root, 800, 400));
stage.show();
}
//[...]
我也累了,从更换整个的ArrayList带有一个ObservableList的“Medienverwaltung”类,这样只剩下一个List,这对于GUI来说是有用的,但是对于我之前猜测的序列化和反序列化来说却没有。 (并尝试了一些其他的实现)
有没有人有一个想法如何改变我的代码,以便它的工作? 而我的第二个问题是,3层架构的最佳方式是什么?
以下是费边参考答案,并回复了我对
更新#1.1(附录进行说明)评论
public interface IDAO {
// Save method
void speichern(List<Medium> liste) throws PersistenzException;
// Load method
List<Medium> laden() throws PersistenzException;
}
这才是我的具体保存方法:
@Override
public void speichern(List<Medium> medienliste) throws PersistenzException{
File sfile = new File("medienliste.dat");
try(FileOutputStream fos = new FileOutputStream(sfile); ObjectOutputStream oos = new ObjectOutputStream(fos)){
oos.writeObject(medienliste);
System.out.println("Serialisierung erfolgreich!");
}catch(IOException e){
e.printStackTrace();
System.out.println("Serialisierung fehlgeschlagen!");
}
}
更新#1.2(附录进行说明)
//[...] section of my GUI for saving
MenuItem speichern = new MenuItem("Speichern");
speichern.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent e){
try{
//Before: medienverwaltung.speichern(medienverwaltung.getMedienliste()); -> doesn't work because of serializing an ObservableList
medienverwaltung.speichern(medienverwaltung.getBackingList());
}catch(PersistenzException pe){
pe.printStackTrace();
}
}
});
//[...]
但正如我猜,这不是一个好方法来访问backinlist这种方式。
更新#2:
尊重一个干净的方式封装的原则,我现在在班上Medienverwaltung增加了一个重载的方法:
public void speichern() throws PersistenzException{
speichern(backingList);
}
所以我的GUI,现在只要求speichern( )。这实际上调用了用于从外部不能访问的备份列表保存的方法。我希望这没有什么不好的编码风格^^
BTW。:如果你读这篇文章,也有类似的问题,不要为同步使用ObservableArrayList与正常列表,这是不行的!改为使用ObservableList。
哦,非常感谢,尽可能地运作。只剩下一个问题,我不允许更改DAO接口(是的,我应该在-.-之前提到,对不起),所以在序列化的时候我仍然遇到问题。从DAO中,我得到以下签名:请参阅更新#1.1 因此,我将我的GUI中的保存方法的调用更改为以下内容:请参阅更新#012 现在可以使用,因为我访问备份列表而不是medienlist,但这不是一个好习惯。 有没有更好的方式我没有看到? –
现在,我认为了一切正确和清洁。 [1.]写了具体的DAO对象类 [2.]将保存/加载方法转换为具体的DAO对象类 [3.]在构造函数中给出了具体的DAO给Medienverwaltung,该构造函数发生在一个不相关的DAO引用中它可以交换) [4.]虽然我仍然使用备份列表,但只是为了给它DAO 所以,非常感谢你帮助我改进我的代码,Fabian = D –