affichage d'une jlist non rafraîchie après des modifs

affichage d'une jlist non rafraîchie après des modifs - Java - Programmation

Marsh Posté le 28-10-2004 à 22:41:41    

Bon, en fait, le titre est un peu faux. La JList se rafraîchit à chaque notifications d'un changement du contenu, mais en fait, elle affiche toujours le même nombre d'élément, ou bug (genre, si l'affichage se fait sur 10 lignes, la dernière colonne s'affiche sur 100 lignes (le reste des éléments de la liste) mais sans scrollbar ni rien, enfin, n'importe quoi en gros), et il faut que je redimensionne la fenêtre par exemple, pour qu'elle affiche correctement le contenu.
 
La Jlist est placée dans un JScrollPane.
 
Voici le modèle :

Code :
  1. public class ListImagesModel extends Observable implements ListModel, Observer {
  2. ...
  3. protected File[] filesList = null;
  4. public ListImagesModel(FSeekerModel fsm) {
  5.  this.fsm = fsm;
  6.  fsm.addObserver(this);
  7.  ... // du blabla qui modifie filesList
  8. }
  9. public void update(Observable o, Object caller) {
  10.  ... // du blabla qui modifie filesList
  11.  setChanged();
  12.  notifyObservers(caller);
  13. }
  14. public int getSize() { return filesList.length; }
  15. public Object getElementAt(int index) { return filesList[index]; }
  16. ...


 
Et là, la vue associée :
 

Code :
  1. public class ListImagesGUI extends JList implements Observer {
  2. protected ListImagesModel m = null;
  3. public ListImagesGUI(ListImagesModel m) {
  4.  this.m = m;
  5.  m.addObserver(this);
  6.  setModel(m);
  7.  setVisibleRowCount(0);
  8.  setLayoutOrientation(JList.VERTICAL_WRAP);
  9. }
  10. public void update(Observable o, Object caller) {
  11.  repaint();
  12.  revalidate();
  13. }
  14. ...


 
En gros, la démarche, c'est : quand je modifie un modèle global, update() dans listimagesmodel se déclenche, rafraichit filesList, et déclenche l'update du listimagesgui, qui se rafraîchit. Or, ca se rafraichit, mais mal !
 
Que puis je faire pour résoudre ça ?

Reply

Marsh Posté le 28-10-2004 à 22:41:41   

Reply

Marsh Posté le 28-10-2004 à 22:51:16    

virer toute ta sousclasse de jlist.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 28-10-2004 à 23:07:42    

euh, hein ?
pas extends JList tu veux dire ?

Reply

Marsh Posté le 28-10-2004 à 23:09:05    

oui. en général on a pas besoin de sous-classe les composants swing. j'irais même jusqu'à dire que ça ne m'est jamais arrivé sauf pour un bidouille avec JLabel (pour les Renderers).


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 28-10-2004 à 23:11:12    

Okas, je vais allez faire en composition alors.

Reply

Marsh Posté le 28-10-2004 à 23:15:43    

oué, c'est mieux


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 28-10-2004 à 23:15:57    

Bon, ça fait toujours pareil.
 
Another idea ?

Reply

Marsh Posté le 28-10-2004 à 23:22:58    

Pour montrer un peu :
 
le mauvais :
http://img25.exs.cx/img25/9427/badgui.th.jpg
 
le bon :
http://img25.exs.cx/img25/549/goodgui.th.jpg

Reply

Marsh Posté le 29-10-2004 à 01:40:57    

[:blueflag]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 29-10-2004 à 06:39:26    

andOcean > vire toutes tes preferred size et minimal sizes.
 
par contre faire un overflow horizontal on évite en général.
 
 
pour ceux qui seraient étonné de voir une liste sur plusieurs colones, il a utilisé  HORIZONTAL_WRAP.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-10-2004 à 06:39:26   

Reply

Marsh Posté le 29-10-2004 à 06:40:34    

la règle générale > si ça dégueule pas dans le bon sens, c'est probablement qu'on a joué avec des machinSize.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-10-2004 à 11:17:25    

Je voudrais bien nraynaud, le problème, c'est que comme tu peux le voir dans le code de mon 1er message, il n'y a aucun machinSize. (et oui, c'est un horizontal_wrap dans les s/s là, pas le vertical_wrap du code dessus ;o)

Reply

Marsh Posté le 29-10-2004 à 11:20:15    

et le visibleRowCount ?

Reply

Marsh Posté le 29-10-2004 à 11:21:52    

je dois t'avouer que j'ai jamais utilisé ça, mais normalement, ça respecte la règle de la surprise minimum, donc, il faut mettre un minimum de configuration.

Reply

Marsh Posté le 29-10-2004 à 11:33:02    

Que je l'enlève, ou que je mettes une constante > 0, ça bug toujours. Et puis, le code dessus, c'est un code simplifié. Il y a plus d'options dans le vrai code, mais je l'ai simplifié au maxi. Et même en mettant plein de config, il est toujours là le bug.

Reply

Marsh Posté le 29-10-2004 à 11:43:02    

justement, vire toute la config.
 
tu veux afficher quoi exactement ? une liste sur plusieurs colones comme dans un journal ?

Reply

Marsh Posté le 29-10-2004 à 11:55:43    

La config est viré ! J'ai tout mis en commentaire, sauf le bout que je montre dans mon 1er message.
 
Je voudrais qu'il affiche correctement _tout_ le contenu, tout simplement. Pour l'instant, comme j'ai dis, il n'affiche pas tout, ou n'importe comment. Il faut que je redimensionne la fenêtre pour mettre à jour correctement.

Reply

Marsh Posté le 29-10-2004 à 12:16:23    

simplement une colone, tout bête ????
 
ben tu fais juste panel.add(new JScrollPane(new JList(tonmodel)));
 
par contre, j'ai un doute, tu utilises quoi comme ListModel ? un truc perso ?

Reply

Marsh Posté le 29-10-2004 à 12:19:02    

Non, pas une seule colonne, regardes les s/s. C'est la version "bonne" que je veux. (mais après, ca dépend juste du wrap, j'utilise les deux dans mon cas, + renderer etc. mais ça n' pas d'influence tout ça).
 
Le ListModel, oui il est perso, voir le code 1er message.

Reply

Marsh Posté le 29-10-2004 à 12:19:45    

merde, j'ai pas été revoir le code là-haut /o\
file-moi le code complet du listmodel stp.

Reply

Marsh Posté le 29-10-2004 à 12:23:33    

Bah, y'a pas grand chose en plus du code en haut.
 

Code :
  1. public class ListImagesModel extends Observable implements ListModel, Observer {
  2. protected MainModel fsm = null;
  3. protected File[] filesList = null;
  4. public ListImagesModel(MainModel fsm) {
  5.  this.fsm = fsm;
  6.  fsm.addObserver(this);
  7.  filesList = getModel().getFilesList();
  8. }
  9. public MainModel getModel() { return fsm; }
  10. public void update(Observable o, Object caller) {
  11.  filesList = getModel().getFilesList();
  12.  setChanged();
  13.  notifyObservers(caller);
  14. }
  15. public int getSize() { return filesList.length; }
  16. public Object getElementAt(int index) { return filesList[index]; }
  17. public void addListDataListener(ListDataListener l) {}
  18. public void removeListDataListener(ListDataListener l) { }
  19. }

Reply

Marsh Posté le 29-10-2004 à 12:38:22    

ok, j'ai trouvé : tu as tout faux sur le pattern listener.
 
tu as le code source du JDK ? va voir la classe DefaultListModel.  
 
 
La JList va enregistrer un éclaireur dans le model par addListDataListener() quand le modèle va se modifier, il doit envoyer un ListDataEvent à tous les Listeners qui se sont enregistrés.  
 
Donc il faut que addListDatalistener mette le listener reçu en paramètre dans une collection et que dans update() tu envoies le bon évènement à chacun des listeners dans la collection.

Reply

Marsh Posté le 29-10-2004 à 12:58:53    

Euh, du genre ...
 

Code :
  1. protected List listeners = new ArrayList();
  2. public void addListDataListener(ListDataListener l) {
  3.  if (l != null && !listeners.contains(l))
  4.   listeners.add(l);
  5. }
  6. public void removeListDataListener(ListDataListener l) {
  7.  if (l != null)
  8.   listeners.remove(l);
  9. }
  10. public void update(Observable o, Object caller) {
  11.  filesList = getModel().getFilesList();
  12.  Iterator it = listeners.iterator();
  13.  while (it.hasNext())
  14.   ((ListDataListener) it.next()).contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, getSize() - 1));
  15.  /*setChanged();
  16.  notifyObservers(caller);*/
  17. }


 
ca ? Et le gui ajoute un listener, dès qu'il reçoit l'événement, fait un revalidate() + repaint() ?

Reply

Marsh Posté le 29-10-2004 à 13:07:06    

Bon, je crois que ça marche, j'ai codé à la va vite l'implémentation du listdatalistener, avec

Code :
  1. public void contentsChanged(ListDataEvent e) {
  2.  gui.getGUI().revalidate();
  3.  gui.getGUI().repaint();
  4. }


et ça fonctionne. Je vais nettoyer un peu, mais c'est bon quoi.
 
Merci beaucoup nraynaud !

Reply

Marsh Posté le 29-10-2004 à 13:12:05    

Tiens, mais en fait, je peux laisser la méthode contentsChanged vide, et décommenter le setChanged() et notifyObservers() de l'update du modèle. Ca fonctionne toujours. Je comprends pas trop pourquoi, je n'ai fait que rajouter le truc qui gère les listeners dont je ne me sert même pas en fait. (meme plus de addListDataListener dans le gui)
 
Enfin, ça marche impec'.
 
edit: ah oui, c'est Swing qui rajoute lui même un listener : javax.swing.plaf.basic.BasicListUI$Handler@b09e89


Message édité par andOceans le 29-10-2004 à 13:16:31
Reply

Marsh Posté le 29-10-2004 à 13:25:37    

voiloù ; fais bien gaffe à envoyer exactement le bon type dévènement dans la bonne situation, mais tu es exactement dans le pattern.

Reply

Marsh Posté le 29-10-2004 à 13:31:04    

Okas. Je viens de soulever un lièvre, ça fait plaisir.
 
Merci bien.

Reply

Marsh Posté le 29-10-2004 à 14:22:14    

nraynaud a écrit :

ok, j'ai trouvé : tu as tout faux sur le pattern listener.
 
tu as le code source du JDK ? va voir la classe DefaultListModel.  
 
 
La JList va enregistrer un éclaireur dans le model par addListDataListener() quand le modèle va se modifier, il doit envoyer un ListDataEvent à tous les Listeners qui se sont enregistrés.  
 
Donc il faut que addListDatalistener mette le listener reçu en paramètre dans une collection et que dans update() tu envoies le bon évènement à chacun des listeners dans la collection.

y'a pas un AbstractListModel qui fait ?
Observable ça devrait pas etre deprecié ce "truc" ?
(andOceans, tu l'utilises dans quel cadre ce Observable/Observer?)


Message édité par the real moins moins le 29-10-2004 à 14:23:19
Reply

Marsh Posté le 29-10-2004 à 15:00:06    

Si, y'a déjà le abstract et le default qui le font. Je l'utilise pour l'architecture MVC (très pratique) de mon application.
J'aurai bien aimé faire un extends Observable, AbstractListModel mais bon, je vais pas troller. :D

Reply

Marsh Posté le 29-10-2004 à 15:16:34    

surtout que sans use case qui tienne la route, tu vas vite tomber à court d'arguments. donc tu utilises l'observer/observable pour?

Reply

Marsh Posté le 29-10-2004 à 15:28:21    

Voir le message précédent. Je n'ai que ça à dire. :d

Reply

Marsh Posté le 29-10-2004 à 15:32:51    

donc  tu etends Observable juste pour dire que ça te fait chier de pas pouvoir faire du double héritage? [:itm]

Reply

Marsh Posté le 29-10-2004 à 15:40:54    

Mais non. Je l'étends pour ne pas l'implémenter.
 
Ce modèle a besoin d'être observable, ie : dans le gui, j'ai m.addObserver(this); avec m, ce modèle, pour que dès que c'est modifié, ça appelle le update() de ce gui. J'ai pas mal de vues, et de modèles dans l'application, j'uniformise tout. Je ne vais pas aller m'amuser à étudier chaque cas pour savoir comment je pourrais faire sans, ça serait contraire à la logique de garder la modularité du MVC.

Reply

Marsh Posté le 29-10-2004 à 15:45:18    

mais le ListModelListener est là pour ça non ? Tu devrais pas avoir à updater la gui "à la main" il me semble :??:

Reply

Marsh Posté le 29-10-2004 à 15:57:30    

Oui, aussi en fait. J'ai tout réécris en utilisant ça, ça fonctionne pareillement, c'est vrai. Et ça me permet de extends l'abstractlistmodel, donc de virer mes méthodes réécrits, sympathique tout compte fait. C'est vrai que c'était assez évident, je devais être enfermé dans mon MVC pur main, pour ne pas y penser. :|

Reply

Marsh Posté le 29-10-2004 à 15:58:16    

et voilà [:djswad]

Reply

Marsh Posté le 29-10-2004 à 16:01:35    

Merci à toi aussi. :love:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed