[Java] Actualisation d'une JList
Résolu/Fermé
A voir également:
- [Java] Actualisation d'une JList
- Jeux java itel ✓ - Forum Jeux vidéo
- Java runtime - Télécharger - Langages
- Java apk - Télécharger - Langages
- Scanf en java ✓ - Forum Java
- Java heap space ✓ - Forum Java
3 réponses
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 004
8 déc. 2011 à 20:48
8 déc. 2011 à 20:48
J'ai du mal à voir où est concrètement utilisée ta liste ad.
Quand tu dis que tu ajoutes un élément à ta liste, il faudrait plutôt avoir une méthode dans ta classe ADList pour faire ça, et qui appellerait directement le model, non ?
Quand tu dis que tu ajoutes un élément à ta liste, il faudrait plutôt avoir une méthode dans ta classe ADList pour faire ça, et qui appellerait directement le model, non ?
J'ai essayé d'utiliser le pattern MVC. Le modèle contient et gère les données (notamment un ArrayList<AnnotatedDialog>).
La vue contient donc l'ADList. Elle contient aussi un bouton permettant d'ajouter un AnnotatedDialog. Quand j'appuie sur ce bouton cela ouvre envoie une instruction au modèle qui ajoute un AnnotatedDialog à sa liste. Puis le modèle notify la vue du changement.
Finalement, la vue, pour se mettre à jour, appel la méthode setADL qui change l'ensemble du contenu de la JList. Mais apparemment, changer le contenu de la JList ne fait pas actualiser automatiquement l'affichage.
J'espère que ce n'est pas trop confus. Si tu as d'autres questions n'hésite pas !
La vue contient donc l'ADList. Elle contient aussi un bouton permettant d'ajouter un AnnotatedDialog. Quand j'appuie sur ce bouton cela ouvre envoie une instruction au modèle qui ajoute un AnnotatedDialog à sa liste. Puis le modèle notify la vue du changement.
Finalement, la vue, pour se mettre à jour, appel la méthode setADL qui change l'ensemble du contenu de la JList. Mais apparemment, changer le contenu de la JList ne fait pas actualiser automatiquement l'affichage.
J'espère que ce n'est pas trop confus. Si tu as d'autres questions n'hésite pas !
J'ai trouvé une "solution" qui ressemble plutôt à un contournement. Pour spécifier au ADListModel qu'il y a eu une modification, j'ai ajouté dans la fonction setADL un appel à DefaultListModel.fireContentsChanged. Ce qui me donne la chose suivante :
La fonction update() est une fonction que j'ai ajoutée à ADListModel puisque la méthode fireContentsChanged n'était pas accessible depuis ADList :
Je trouve que ça fait un peu bidouillage alors que j'essayais de faire un truc propre... Vous en pensez quoi ?
public void setADL(ArrayList<AnnotatedDialog> ad_arg){ ad = ad_arg; ((ADListModel)this.getModel()).update(); }
La fonction update() est une fonction que j'ai ajoutée à ADListModel puisque la méthode fireContentsChanged n'était pas accessible depuis ADList :
public void update(){ this.fireContentsChanged(ad, 0, ad.size()); }
Je trouve que ça fait un peu bidouillage alors que j'essayais de faire un truc propre... Vous en pensez quoi ?
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 004
8 déc. 2011 à 23:11
8 déc. 2011 à 23:11
Ce qui n'est pas propre c'est la manière dont tu utilises ad, je trouve ça vraiment bizarre...
Ensuite je ne vois pas l'intérêt de ADListCellRenderer, mais je ne vais pas trop m'avancer là dessus, il faudrait que je testes vraiment ce qu'il en est...
Ensuite je ne vois pas l'intérêt de ADListCellRenderer, mais je ne vais pas trop m'avancer là dessus, il faudrait que je testes vraiment ce qu'il en est...
/** Le Model manipule les données */ class ADListModel extends AbstractListModel { private static final long serialVersionUID = 1; private ArrayList<AnnotatedDialog> ad; public ADListModel(ArrayList<AnnotatedDialog> ad_arg) { ad=ad_arg; } @Override public int getSize() { return ad.size(); } @Override public Object getElementAt(int index) { return ad.get(index).getFileName(); } public ArrayList<AnnotatedDialog> getAD() { return ad; } public void setAD(ArrayList<AnnotatedDialog> ad_arg) { ad=ad_arg; } } /** La JList manipule le Model */ public class ADList extends JList { private static final long serialVersionUID = 1; private final ADListModel model; public ADList(ArrayList<AnnotatedDialog> ad_arg) { model = new ADListModel(ad_arg); setModel(model); } public void setADL(ArrayList<AnnotatedDialog> ad_arg) { model.setAD(ad_arg); } public ArrayList<AnnotatedDialog> getAD() { return model.getAD(); } }
Le ADListCellRenderer me permet de customiser l'affichage. Par exemple pour qu'une ligne sur d'eu soit d'une couleur différente je fais ça :
J'ai fais les modifications que tu préconise (ie. passer l'ArrayList<AnnotatedDialog> dans le model et y ajouter les @Override ainsi qu'une méthode setAD). Cependant pour que les changements soient pris en compte, il faut toujours que j'utilise la fonction "fireContentsChanged". La seule modification est que cette fonction est maintenant appellée dans setAD (du modèle) et plus setADL (de la JList).
C'est plus propre mais la mise à jour nécessite toujours fireContentsChanged. Je me dit que si tout était bien fait je n'aurais pas besoin de cet appel et tout devrait se faire tout seul.
public class ADListCellRenderer extends DefaultListCellRenderer{ public Component getListCellRendererComponent( JList list, Object value, // value to display int index, // cell index boolean iss, // is the cell selected boolean chf) // the list and the cell have the focus { super.getListCellRendererComponent(list, value, index, iss, chf); if( index %2 == 1 ) this.setBackground(new Color(231, 219, 249)); return this; } }
J'ai fais les modifications que tu préconise (ie. passer l'ArrayList<AnnotatedDialog> dans le model et y ajouter les @Override ainsi qu'une méthode setAD). Cependant pour que les changements soient pris en compte, il faut toujours que j'utilise la fonction "fireContentsChanged". La seule modification est que cette fonction est maintenant appellée dans setAD (du modèle) et plus setADL (de la JList).
C'est plus propre mais la mise à jour nécessite toujours fireContentsChanged. Je me dit que si tout était bien fait je n'aurais pas besoin de cet appel et tout devrait se faire tout seul.
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 004
9 déc. 2011 à 14:32
9 déc. 2011 à 14:32
Je pense que le problème vient que tu tiens absolument à passer tes données dans ad au lieu d'utiliser directement les données de la liste. Si tu prends DefaultListModel au lieu de AbstractListModel, c'est tout de suite plus simple car tu peux directement faire des get et des set sur tes données.
public class ADList extends JList { private static final long serialVersionUID = 1; private final DefaultListModel model; public ADList(ArrayList<AnnotatedDialog> ad_arg) { model = new DefaultListModel(); setADL(ad_arg); } public void setADL(ArrayList<AnnotatedDialog> ad_arg) { model.clear(); for (AnnotatedDialog a : ad_arg) model.addElement(a); } public ArrayList<AnnotatedDialog> getAD() { int n=model.getSize(); ArrayList<AnnotatedDialog> ad = new ArrayList<AnnotatedDialog>(n); for (int i=0; i<n; i++) ad.set(i, (AnnotatedDialog) model.get(i)); return ad; } }
Effectivement ça marche très bien avec les fonctions clear et addElement ! Je peux donc supprimer ma classe ADListModel.
J'ai juste modifié l'appel de addElement pour lui passer en argument a.getFileName() plutôt que a. Sinon il ne sait pas quoi m'afficher et ça donne des trucs comme ça : model.AnnotatedDialog@19f6a57.
Merci beaucoup de ton aide et du temps que tu as passé à comprendre mon cas tordu et à écrire le code des corrections !
J'ai juste modifié l'appel de addElement pour lui passer en argument a.getFileName() plutôt que a. Sinon il ne sait pas quoi m'afficher et ça donne des trucs comme ça : model.AnnotatedDialog@19f6a57.
Merci beaucoup de ton aide et du temps que tu as passé à comprendre mon cas tordu et à écrire le code des corrections !
KX
Messages postés
16668
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2023
3 004
9 déc. 2011 à 17:54
9 déc. 2011 à 17:54
model.AnnotatedDialog@19f6a57 c'est typiquement parce qu'il n'y a pas de toString redéfini pour AnnotatedDialog, là encore je pense que c'est parce qu'il affiche a au lieu de a.getFileName()