Serialization JavaFX,列表到可观察列表到列表视图

Serialization JavaFX,列表到可观察列表到列表视图,serialization,arraylist,javafx,dao,observablelist,Serialization,Arraylist,Javafx,Dao,Observablelist,所以我的问题是,我有一个系列化的ArrayList,必须在GUI中更新它,以便在ListView中动态显示其内容。 序列化和反序列化可以很好地使用DAO接口,但GUI不会刷新我的ListView 此类保存我的数据交互(主要是保存、加载…): 因此,我的GUI现在只调用speichen()。这实际上调用了使用backedlist保存的方法,backedlist无法从外部访问。我希望这不是一种糟糕的编码风格^^ 顺便说一句:如果您正在阅读此文章,并且遇到类似问题,请不要使用ObservableArr

所以我的问题是,我有一个系列化的ArrayList,必须在GUI中更新它,以便在ListView中动态显示其内容。 序列化和反序列化可以很好地使用DAO接口,但GUI不会刷新我的ListView

此类保存我的数据交互(主要是保存、加载…):

因此,我的GUI现在只调用speichen()。这实际上调用了使用backedlist保存的方法,backedlist无法从外部访问。我希望这不是一种糟糕的编码风格^^

顺便说一句:如果您正在阅读此文章,并且遇到类似问题,请不要使用ObservableArrayList与正常的列表进行同步,这将不起作用!改为使用observeList

通过删除getter从其他类隐藏支持列表(
mediEnlist
)。如果使用
可观察列表
修改此列表,则
列表视图
(或已向列表添加侦听器的所有其他对象)将正确更新

此外,除非
Medium
扩展
节点
,否则您可以简单地将此类对象用作
列表视图
的项,因为单元格将文本设置为默认情况下为关联项调用的
toString
方法的结果

public class Medienverwaltung implements Serializable, IDAO{

    private static final long serialVersionUID = 1L;
    private List<Medium> backingList;

    // transient field not persisted
    private transient ObservableList<Medium> medienliste;

    public Medienverwaltung(){
        backingList = new ArrayList<Medium>();
        medienliste = FXCollections.observableArrayList(backingList);
    }

    // make sure an ObservableList is created when reading the serialized object
    private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
        inputStream.defaultReadObject();
        medienliste = FXCollections.observableArrayList(backingList);
    }  

    //[...]

    public ObservableList<Medium> getMedienliste(){
        return this.medienliste;
    }

    //[...]

}
通过删除getter,对其他类隐藏支持列表(
mediEnlist
)。如果使用
可观察列表
修改此列表,则
列表视图
(或已向列表添加侦听器的所有其他对象)将正确更新

此外,除非
Medium
扩展
节点
,否则您可以简单地将此类对象用作
列表视图
的项,因为单元格将文本设置为默认情况下为关联项调用的
toString
方法的结果

public class Medienverwaltung implements Serializable, IDAO{

    private static final long serialVersionUID = 1L;
    private List<Medium> backingList;

    // transient field not persisted
    private transient ObservableList<Medium> medienliste;

    public Medienverwaltung(){
        backingList = new ArrayList<Medium>();
        medienliste = FXCollections.observableArrayList(backingList);
    }

    // make sure an ObservableList is created when reading the serialized object
    private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
        inputStream.defaultReadObject();
        medienliste = FXCollections.observableArrayList(backingList);
    }  

    //[...]

    public ObservableList<Medium> getMedienliste(){
        return this.medienliste;
    }

    //[...]

}

哦,非常感谢,这尽可能有效。只剩下一个问题,我不允许更改DAO接口(是的,我应该在之前提到-。-',对不起),因此我在序列化时仍然存在问题。从DAO中,我得到了以下签名:请参阅更新#1.1,因此我将GUI中保存方法的调用更改为:请参阅更新#1.2这现在可以工作了,因为我访问backinglist而不是medienlist,但这不是一个好的实践。有没有更好的方法我还没看到呢?我想现在一切都正确干净了。[1.]编写了具体的DAO对象类[2.]将保存/加载方法转移到具体的DAO对象类[3.]将具体的DAO通过构造函数传递给了MedienVoltung,这发生在一个不具体的DAO引用中(以使其可交换)[4.]虽然我仍然使用backinglist,但只是为了将其传递给DAO So,非常感谢您帮助我改进代码,Fabian=DOh非常感谢,这将尽可能有效。只剩下一个问题,我不允许更改DAO接口(是的,我应该在之前提到-。-',对不起),因此我在序列化时仍然存在问题。从DAO中,我得到了以下签名:请参阅更新#1.1,因此我将GUI中保存方法的调用更改为:请参阅更新#1.2这现在可以工作了,因为我访问backinglist而不是medienlist,但这不是一个好的实践。有没有更好的方法我还没看到呢?我想现在一切都正确干净了。[1.]编写了具体的DAO对象类[2.]将保存/加载方法转移到具体的DAO对象类[3.]将具体的DAO通过构造函数传递给了MedienVoltung,这发生在一个不具体的DAO引用中(以使其可交换)[4.]虽然我仍然使用backinglist,但只是为了将其传递给DAO So,非常感谢您帮助我改进代码Fabian=D
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!");
    }
}
//[...]  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();
            }
        }
    });
//[...]
public void speichern() throws PersistenzException{
    speichern(backingList);
}
public class Medienverwaltung implements Serializable, IDAO{

    private static final long serialVersionUID = 1L;
    private List<Medium> backingList;

    // transient field not persisted
    private transient ObservableList<Medium> medienliste;

    public Medienverwaltung(){
        backingList = new ArrayList<Medium>();
        medienliste = FXCollections.observableArrayList(backingList);
    }

    // make sure an ObservableList is created when reading the serialized object
    private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
        inputStream.defaultReadObject();
        medienliste = FXCollections.observableArrayList(backingList);
    }  

    //[...]

    public ObservableList<Medium> getMedienliste(){
        return this.medienliste;
    }

    //[...]

}
@Override
public void start(Stage stage) throws Exception{
    medienverwaltung = new Medienverwaltung();

    VBox root = new VBox();
    ListView<Medium> showliste = new ListView<>(medienverwaltung.getMedienliste());

    MenuBar menuBar = createMenuBar(stage);
    root.getChildren().add(menuBar);
    root.getChildren().add(showliste);

    // 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();   
}
IDAO idao = new IDAOImplementation();
Medienverwaltung medienverwaltung = new Medienverwaltung(idao.laden());
public void handle(ActionEvent e){
    try{
        idao.speichern(medienverwaltung.getMedienliste());
    }catch(PersistenzException pe){
        pe.printStackTrace();
    }
}
public Medienverwaltung(List<Medium> medien) {
    this.medienliste = FXCollections.observableArrayList(medien);
}
@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(new ArrayList(medienliste));
        System.out.println("Serialisierung erfolgreich!");
    } catch(IOException e){
        throw new PersistenzException(e);
    }
}