IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants Java Discussion :

Redimentionnement d'un noeud dans le DefaultTreeCellRenderer


Sujet :

Composants Java

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut Redimentionnement d'un noeud dans le DefaultTreeCellRenderer
    Bonjour,

    je travaille actuellement sur la mise à jour d'un projet qui représente l'état d'un hardware. voici le contexte :

    le hardware m'envoie des informations sur son état. Pour faire cela, il met à jour un modelle (classe java) qui contient toutes les informations qui me sont utiles.

    J'ai un Jtree qui represente les différents composants de mon hardware et qui se met à jour quand le modelle est mis à jour. Cette mise à jour prend deux formes, soit je mets un icone pour donner l'état du hardware (en fonctionnement, etat dégradé, en panne), soit je mets à jour le noeud pour mettre par exemple la température.

    voici comment a été initialiser le Jtree :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    private void listComposant() {
     
    	DefaultMutableTreeNode racine = new DefaultMutableTreeNode(modele.getSystem().getIdent().getFullName());
    	listcomposant = modele.getSonarSystem().getContent();
     
    	for (MonComposant composant : listcomposant.getItems()) {
     
    		nom = composant.getIdent().getFullName();
     
    		if (composant instanceof CompInfo) {
    			nom += " : " + ((CompInfo) composant).getInfo();
    			((CompInfo) composant).addListener(infoListener);
                            mapModele.put(((CompStatus) composant ).getStatus(), subNode);
    		}else if (composant  instanceof CompStatus) {
    			((CompStatus) composant ).getStatus().addVariableListener(StatusListener);
    			mapModele.put(((CompStatus) composant ).getStatus(), subNode);
    		}
     
    		DefaultMutableTreeNode node = new DefaultMutableTreeNode(nom);
     
    		racine.add(node);
     
    	}
     
    	status = new TreeStatus(this);
    	arbre = new JTree(this.racine);
    	arbre.setRootVisible(true);
    	arbre.setCellRenderer(status);
    	arbre.setVisible(true);
     
    }
    les 2 listeners qui sont utilisés font un repaint de l'arbre. La map me permet de lier l'objet du modelle à un noeud de mon arbre.

    Pour la mise à jour de l'arbre j'ai la classe TreeStatus qui étend DefaultTreeCellRenderer ou j'ai surchargé getTreeCellRendererComponent comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
    			boolean leaf, int row, boolean hasFocus) {
     
    	super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
     
    	MonComposant composant = arbrePanel.getModeleMap().get((TreeNode) value);
     
    	if (composant instanceof CompStatus) {
    		StatusEnum statut = ((CompStatus) composant).getStatus().getValue();
    	// get the status' icon
    	switch (statut) {
    		case TDAMAGED:
    			setIcon(new ImageIcon("cercle-orange-icone.png"));
    			break;
    		case TNOMINAL:
    			setIcon(new ImageIcon("cercle-vert-icone.png"));
    			break;
    		case TFAILED:
    			setIcon(new ImageIcon("cercle-rouge-icone.png"));
    			break;
    		case TUNKNOWN:
    		case TNOTTESTED:
    			setIcon(new ImageIcon("cercle-gris-icone.png"));
    			break;
    		default:
    			setIcon(new ImageIcon("cercle-gris-icone.png"));
    			break;
    		}
    	}else {//case of comp info and racine
    		if(composant instanceof CompInfo){
    		    String text = composant.getIdent().getFullName() + " : " + ((CompInfo)composant).getInfo();
                        ((DefaultMutableTreeNode)value).setUserObject(text);
    		    setText(text);
     
    		}
    		setIcon(null);
    	}
     
    	return this;
     
    }
    La mise à jour de l'icone fonctionne très bien, par contre la mise à jour du noeud (dans le else) pose un souci, car losque le text affiché est plus grand que le text original il se termine par "...". J'ai pas mal parcourus le net avant de poster, et les différentes possibilités que j'ai trouvé ne fonctionnent pas.

    J'ai essayer d'ajouter à l'init de l'arbre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    arbre.setLargeModel(true); //ne fonctionne pas
    j'ai essayé de faire des validate, revalidate, repaint apres le settext ça ne fonctionne pas non plus.
    J'ai essayé de faire un setSize(), un setPreferedSize(); pas mieux.
    j'ai essayé de cumuler les 2 solutions précedentes, rien y fait.

    Les solutions que j'ai trouvé par ailleur se faisaient hors du DefaultCellRenderer du coup elles ne sont pas applicables à mon cas.

    remarque personnelle : je pense qu'il aurait fallut mettre directement les objets du modelle de stockage de l'état du harware dans l'arbre pour éviter de faire des listener inutiles qui ne font qu'un repaint de l'arbre. Et ensuite gérer l'affichage dans les TreecellRenderer tel que c'est fait maintenant, mais je ne pense pas que cela résoudra mon problème de taille du noeud.

    si vous avez une idée de ce qui m'échappe pour resizer le Jlabel du noeud je suis prenneur.

    cordialement,

    Obtraba

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    peut être que ça t’intéressera :
    http://www.coderanch.com/t/344875/GU...nager-resizing
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Bonjour,

    merci !!!! Je commencais à désespérer. Ca m'a l'air de correspondre à ce dont j'ai besoin. Je vais tester cette solution, je reviens vers vous, pour vous dire ce qu'il en est.

    Je vais passer un meilleur weekend

  4. #4
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Note that although DefaultMutableTreeNode has methods for changing a node's content, changes should go through the DefaultTreeModel cover methods. Otherwise, the tree model events would not be generated, and listeners such as the tree would not know about the updates.

    in Dynamically Changing a Tree
    En gros, soit tu écris ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    assert SwingUtilities.isEventDispatchThread();
    myDefaultMutableTreeNode.setUserObject("blabla");
    myDefaultTreeModel.nodeChanged(myDefaultMutableTreeNode);
    Soit tu écris ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    assert SwingUtilities.isEventDispatchThread();
    TreePath path = new TreePath(myDefaultTreeModel.getPathToRoot(myDefaultMutableTreeNode);
    myDefaultTreeModel.valueForPathChanged(path, "blabla");
    Mais tu n’écris pas ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    assert SwingUtilities.isEventDispatchThread();
    myDefaultMutableTreeNode.setUserObject("blabla");
    ...
    myDefaultTree.repaint(); // N’est ni nécessaire ni suffisant.
    Parce que le dernier repaint de l’arbre va bien utiliser la valeur courante du noeud, mais n’aura pas été mis au courant de son changement (de ce point de vue, l’utilisation de setLargeModel n’était pas complètement déplacée). C’est d’ailleurs pour ce même type de raison que toute modification et notification de l’IHM doit se faire atomiquement dans l’EDT.

    P.S. Le lien donné dans le précédent message ne correspond pas à ton besoin : tu n’as pas envie de redimensionner tes libellés dynamiquement à la largeur de l’arbre, mais de redimensionner tes libellés à la largeur de leur nouveau contenu.

  5. #5
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Bonjour, merci pour ta réponse Chatanga.

    J'avais déjà essayé ce que tu proposes, mais je ne peux pas l'appliquer dans mon cas, car cela génère une boucle infinit.

    En effet les méthodes nodeChange() et valueForPathChanged() appelle la fonction getTreeCellRendererComponent() du DefaultTreeCellRenderer. Hors je suis déjà dans cette fonction. Donc, je m'appelle de façon récursive à l'infinit.
    Je ne sais pas si le assert que tu proposes dans ta solution est censé protéger de la boucle infinit mais dans mon cas ça ne fonctionne pas.

    La solution du lien fonctionne très bien, et après affichage du preferedSise de mon noeud (pour vérifier ta remarque), il est bien redimentionné à sa nouvelle taille et pas à la taille de l'arbre.

    Je passe donc ce topic à Résolut.

  6. #6
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Je n’avais pas vu que tu modifiais le modèle dans la vue. C’est mal. Ce n’est pas seulement contraire au MVC, c’est juste pas cohérent qu’une fonction de dessin modifie en même temps l’objet dessiné. Je ne parle même pas des performances : à chaque fois que tu dessines ton arbre, tu demandes à Swing de le redessiner. Ce n’est pas pour autant une boucle infinie, modifier le modèle provoque essentiellement un repaint, c’est à dire une demande pour être redessiné "later". Si tu as une boucle infinie, ça suggère que tu as fait un truc pas net au niveau d’un écouteur du modèle.

    Par ailleurs, le code de JavaRanch que tu réutilises ne fonctionne pas comme tu le penses. Tu le détournes de son usage et profites simplement indirectement de ce bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    private void registerUI() {  
            SwingUtilities.invokeLater(new Runnable() {  
                public void run() {  
                    tree.setUI(new BasicWideNodeTreeUI());  
                }  
            });  
        }
    Tu pourrais obtenir le même résultat et éviter ta boucle infinie en faisant la même chose avec mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    myDefaultMutableTreeNode.setUserObject("blabla");
    SwingUtilities.invokeLater(new Runnable() {  
    	public void run() {  
    		myDefaultTreeModel.nodeChanged(myDefaultMutableTreeNode);
    	}  
    });
    Dans un cas comme dans l’autre, ça ne corrige toutefois pas ton problème de fond.

  7. #7
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Je suis d'accord avec tout ce que tu dis. Mais je ne suis pas à l'origine de la conception de l'arbre, et à la base il y a un problème de design. Les objets que j'utilisent pour dessiner l'arbre ne supportent pas les listeners. Du coup je me retrouve à récupérer l'information dans le process de dessin au lieu de le traiter en amont.

    le code qu'il y a ici n'est qu'un tout petit bout de l'iceberg... à mon grand désespoir.

    Pour finir avec le invokelater il n'y a plus de boucle infinie. Donc je vais prendre ta solution.

    merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Enlver un noeud dans une structure XML
    Par Sharingan dans le forum ASP
    Réponses: 4
    Dernier message: 20/12/2004, 08h08
  2. [VB.NET] [XML] Suppression d'un noeud dans un fichier XML
    Par Hoegaarden dans le forum Windows Forms
    Réponses: 2
    Dernier message: 24/09/2004, 11h24
  3. Stocker un noeud dans une variable
    Par Devotion dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 23/09/2004, 17h02
  4. Pbs pour Glisser-Deplacer des noeuds dans un TreeView.
    Par psau dans le forum C++Builder
    Réponses: 3
    Dernier message: 08/09/2004, 21h02
  5. Insertion d'un noeud dans une liste chaînée
    Par habib106 dans le forum Assembleur
    Réponses: 8
    Dernier message: 07/04/2004, 22h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo