Donc mon problème est, que j'ai un ArrayList serilized et dois le mettre à jour dans mon GUI pour montrer son contenu dans un ListView dynamiquement. La sérialisation et la désérialisation fonctionnent correctement avec l'utilisation d'une interface DAO, mais l'interface graphique n'actualisera pas ma ListView.JavaFX, Liste à ObservableList à ListView
Cette classe contient mon interaction de données (sauf la plupart du temps, charge ...):
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;
}
//[...]
}
vient ici mon interface graphique extrait de mise en œuvre:
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();
}
//[...]
J'ai aussi fatigué d'échanger toute ArrayList de la classe "Medienverwaltung" avec un ObservableList, de sorte qu'il ne reste qu'une seule liste, qui fonctionne pour l'interface graphique mais pas pour la sérialisation et la désérialisation comme je l'ai deviné auparavant. (et essayé quelques autres implémentations)
Est-ce que quelqu'un a une idée comment changer mon code pour que cela fonctionne? Et ma deuxième question est, quelle est la meilleure façon en termes d'architecture à 3 couches?
Ce qui suit est une référence à fabiens réponse et répond à mon commentaire sur cette
Mise à jour # 1.1 (additif pour explication)
public interface IDAO {
// Save method
void speichern(List<Medium> liste) throws PersistenzException;
// Load method
List<Medium> laden() throws PersistenzException;
}
vient ici mon béton méthode de sauvegarde:
@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!");
}
}
Mise à jour # 1.2 (additif pour explication)
//[...] 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();
}
}
});
//[...]
Mais comme je suppose, ce n'est pas un bon moyen d'accéder à la backinlist de cette façon.
Mise à jour # 2:
à respecter le principe d'encapsulation d'une manière propre, je maintenant ajouté une méthode surchargée dans la classe Medienverwaltung:
public void speichern() throws PersistenzException{
speichern(backingList);
}
Donc, mon GUI maintenant appelle seulement speichern (). Cela appelle en fait la méthode d'enregistrement avec la liste de diffusion qui n'est plus accessible de l'extérieur. J'espère que ce n'est pas mauvais style de codage ^^
BTW .: Si vous lisez ceci et ont un problème similaire, ne pas utiliser ObservableArrayList pour la synchronisation avec une normale Liste, cela ne fonctionnera pas ! Utilisez ObservableList à la place.
Oh merci beaucoup, cela fonctionne autant que possible. Il n'y a qu'un seul problème reste, je ne suis pas autorisé à changer l'interface DAO (Oui, je l'ai dit avant que -.- », désolé) et j'ai encore des problèmes lors de la sérialisation. A partir de la DAO, je reçois les signatures suivantes: Voir Mise à jour # J'ai donc changé l'appel de ma méthode d'enregistrement dans ma GUI à la suivante: Voir Mise à jour # 1.2 Cela fonctionne maintenant, parce que j'accède à la backinglist au lieu de la medienlist, mais Ce n'est pas une bonne pratique. Y at-il un meilleur moyen que je n'ai pas encore vu? –
Tout est correct et propre maintenant je pense. [1.] a écrit la classe d'objet DAO concrète [2.] les méthodes save/load transférées à la classe d'objets concrète DAO [3.] ont donné DAO concret à Medienverwaltung sur le constructeur, qui se déroule dans une référence DAO non-concédée (pour faire il est échangeable) [4.] bien que j'utilise toujours la backinglist, mais seulement pour la donner au DAO Alors, merci beaucoup de m'avoir aidé à améliorer mon code, Fabian = D –