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 :

[JTree] Problème de lazy load


Sujet :

Composants Java

  1. #1
    Membre confirmé Avatar de heid
    Profil pro
    Inscrit en
    mai 2002
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : mai 2002
    Messages : 388
    Points : 587
    Points
    587
    Par défaut [JTree] Problème de lazy load
    Bonjour,

    j'utilise un type de treenode qui me permet de lazy loader les noeuds enfants :

    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
    package forms;
     
    import java.lang.reflect.Field;
     
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.MutableTreeNode;
     
    public class FieldTreeNode extends DefaultMutableTreeNode {
    	public boolean isFake = true;
     
    	private Object target;
     
    	public FieldTreeNode(Object target) {
     
    		super(target.getClass().getName() + " - " + target.toString());
    		this.target = target;
    		this.add(new DefaultMutableTreeNode("FK"));
    	}
    	public void GetChilds() {
     
    		isFake = false;
    		this.removeAllChildren();
     
    		Class cl = target.getClass();
     
    		for (Field field : cl.getFields()) {
    			try 
    			{			
    				Object a = field.get(target);
    				FieldTreeNode ftn = new FieldTreeNode(a);				
    				this.add((MutableTreeNode)ftn);				
    			} 
    			catch (Throwable t) 
    			{
    				t.printStackTrace();
    			}
    		}
    	}
    }

    de plus, je gère l'évènement treenodewillexpand pour demander au noeud de me renvoyer ses enfants si il est déroulé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {			
    			TreePath myPath = event.getPath();
    			if (myPath != null)
    			{				
    				FieldTreeNode ftn = (FieldTreeNode) myPath.getLastPathComponent();
    				if (ftn.isFake)
    				{
    					ftn.GetChilds();
    				}				
    			}
    			tree.updateUI();					
    		}
    		});
    Or, j'ai une belle exception non gèrée lors de l'appel de updateUI(). Si je n'apelle pas la mise à jour du treenode, pas d'exception mais pas de mise à jour de mes enfants non plus...

    détail de l'exception :
    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
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at javax.swing.plaf.basic.BasicTreeUI.updateSize(BasicTreeUI.java:1709)
    	at javax.swing.plaf.basic.BasicTreeUI.toggleExpandState(BasicTreeUI.java:2190)
    	at javax.swing.plaf.basic.BasicTreeUI.handleExpandControlClick(BasicTreeUI.java:2176)
    	at javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl(BasicTreeUI.java:2130)
    	at javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelectionImpl(BasicTreeUI.java:3495)
    	at javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelection(BasicTreeUI.java:3480)
    	at javax.swing.plaf.basic.BasicTreeUI$Handler.mousePressed(BasicTreeUI.java:3461)
    	at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:222)
    	at java.awt.Component.processMouseEvent(Component.java:5485)
    	at javax.swing.JComponent.processMouseEvent(JComponent.java:3126)
    	at java.awt.Component.processEvent(Component.java:5253)
    	at java.awt.Container.processEvent(Container.java:1966)
    	at java.awt.Component.dispatchEventImpl(Component.java:3955)
    	at java.awt.Container.dispatchEventImpl(Container.java:2024)
    	at java.awt.Component.dispatchEvent(Component.java:3803)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
    	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3889)
    	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
    	at java.awt.Container.dispatchEventImpl(Container.java:2010)
    	at java.awt.Window.dispatchEventImpl(Window.java:1774)
    	at java.awt.Component.dispatchEvent(Component.java:3803)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
    	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
    Merci d'avance.

  2. #2
    Membre expert
    Avatar de natha
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : janvier 2006
    Messages : 2 346
    Points : 3 083
    Points
    3 083
    Par défaut
    Salut,

    #updateUI() est une méthode permettant de mettre à jour le composant en cas de changement de LnF par exemple. Ca n'a donc rien à faire là.
    Pour signifier à ton arbre qu'un noeud a été modifié, tu dois utiliser le TreeModel. S'il s'agit d'un DefaultTreeModel, alors c'est tout facile, tu as plusieurs méthodes événementielles comme #nodeChanged(..) par exemple.

    Par contre moi je fais + ou - comme toi (listener treeWillExpand et ajout des noeuds via une méthode dédiée) et je n'ai absolument pas besoin d'envoyer le moindre événement pour que les sous-noeuds soient ajoutés correctement.

    ++
    Comment ça ? La réponse à ton problème n'est ni dans la faq, ni dans les tutos, ni dans sources ??? Etonnant...
    De la bonne manière de poser une question (et de répondre).
    Je ne fais pas de service par MP. Merci (...de lire les règles...).
    Ma page dvp.com

  3. #3
    Membre confirmé Avatar de heid
    Profil pro
    Inscrit en
    mai 2002
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : mai 2002
    Messages : 388
    Points : 587
    Points
    587
    Par défaut
    En fait, les noeuds sont ajoutés correctement en mémoire, mais pas lors de l'affichage graphique, le composant ne se "databind" pas. Lors de l'apel de updateUI je vois s'afficher correctement les noeuds avant l'exception.

  4. #4
    Membre expert
    Avatar de natha
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : janvier 2006
    Messages : 2 346
    Points : 3 083
    Points
    3 083
    Par défaut
    Ce code marche très bien :

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    import java.awt.Cursor;
     
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JScrollPane;
    import javax.swing.JTree;
    import javax.swing.SwingUtilities;
    import javax.swing.event.TreeExpansionEvent;
    import javax.swing.event.TreeWillExpandListener;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.ExpandVetoException;
    import javax.swing.tree.MutableTreeNode;
     
    public class TestFrame extends JFrame {
     
    	public TestFrame() {
    		super("Test lazy load nodes");
    		initComponents();
    	}
     
    	private void initComponents() {
    		DefaultMutableTreeNode root = new DefaultMutableTreeNode("ROOT");
    		DefaultTreeModel model = new DefaultTreeModel(root);
    		buildTree(root);
    		JTree tree = new JTree(model);
    		tree.setShowsRootHandles(false);
    		tree.setRootVisible(false);
     
    		tree.addTreeWillExpandListener(new TreeWillExpandListener() {
    			@Override
    			public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
    				Object obj = event.getPath().getLastPathComponent();
    				MyTreeNode node = null;
    				if (obj != null && obj instanceof MyTreeNode) {
    					node = (MyTreeNode) obj;
    					if (node.isTempChild()) {
    						try {
    							JOptionPane.getFrameForComponent(getContentPane()).setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    							node.doLoadChildren();
    						} catch (Throwable t) {
    							throw new ExpandVetoException(event, "Error getting childs.");
    						} finally {
    							JOptionPane.getFrameForComponent(getContentPane()).setCursor(Cursor.getDefaultCursor());
    						}
    					}
    				}
    			}
    			@Override
    			public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
    				// Nothing
    			}
    		});
     
    		this.getContentPane().add(new JScrollPane(tree));
    		this.setSize(400, 400);
    		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    	}
     
    	/**
             * @return The builded root node for the JTree
             */
    	private void buildTree(DefaultMutableTreeNode root) {
    		MyTreeNode test = new MyTreeNode();
    		test.add(new TempNode());
    		root.add(test);
    	}
     
    	public static void main(String[] args) {
    		final TestFrame frame = new TestFrame();
    		SwingUtilities.invokeLater(new Runnable() {
    			@Override
    			public void run() {
    				frame.setVisible(true);
    			}
    		});
    	}
     
    	public class MyTreeNode extends DefaultMutableTreeNode {
    		protected boolean m_tempChild;
    		public MyTreeNode() {
    			super("Test");
    		}
    		public MyTreeNode(String name) {
    			super(name);
    		}
    		public final boolean isTempChild() {
    			return m_tempChild;
    		}
    		@Override
    		public void insert(MutableTreeNode newChild, int childIndex) {
    			if (newChild instanceof TempNode) {
    				m_tempChild = true;
    			}
    			super.insert(newChild, childIndex);
    		}
    		public void doLoadChildren() {
    			if (!allowsChildren) {
    				throw new IllegalArgumentException("This TreeNode does not allow children.");
    			}
    			removeAllChildren();
    			addChildren();
    			m_tempChild = false;
    		}
    		public void addChildren() {
    			this.add(new MyTreeNode("1"));
    			this.add(new MyTreeNode("2"));
    			this.add(new MyTreeNode("3"));
    			MyTreeNode test = new MyTreeNode("Test");
    			test.add(new TempNode());
    			this.add(test);
    		}
    	}
     
    	public class TempNode extends DefaultMutableTreeNode {
    		@Override
    		public String toString() {
    			return "...";
    		}
    	}
     
    }
    Et il n'y a aucun évènement particulier ni de raffraichissement.

    Mais ton problème peut être dû au fait que tu appelles updateUI() hors de l'EDT.
    Comment ça ? La réponse à ton problème n'est ni dans la faq, ni dans les tutos, ni dans sources ??? Etonnant...
    De la bonne manière de poser une question (et de répondre).
    Je ne fais pas de service par MP. Merci (...de lire les règles...).
    Ma page dvp.com

  5. #5
    Membre confirmé Avatar de heid
    Profil pro
    Inscrit en
    mai 2002
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : mai 2002
    Messages : 388
    Points : 587
    Points
    587
    Par défaut
    En effet ce code fonctionne, je l'ai repris de base pour l'adapter a mon besoin, merci.

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

Discussions similaires

  1. Problème avec le lazy loading
    Par Arsenic68 dans le forum Entity Framework
    Réponses: 0
    Dernier message: 07/07/2010, 16h51
  2. Problème de Lazy Loading
    Par menzlitsh dans le forum JPA
    Réponses: 1
    Dernier message: 11/02/2009, 16h37
  3. problème de lazy load
    Par nean_j dans le forum JPA
    Réponses: 4
    Dernier message: 01/09/2008, 14h44
  4. Problème de lazy load
    Par breezer911 dans le forum Hibernate
    Réponses: 1
    Dernier message: 13/08/2007, 16h11
  5. [hibernate] problème pour desactiver le lazy loading
    Par agougeon dans le forum Hibernate
    Réponses: 2
    Dernier message: 14/03/2006, 12h20

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