2010-01-28 5 views
8

J'ai un objet simple qui s'étend JPanel, lorsque la méthode update() est appelée sur cet objet, cela signifiait ajouter quelques étiquettes au panneau, puis repeindre. Toutefois, les étiquettes ne se présentent pas après la méthode de mise à jour est appelée, ci-dessous est le code de mise à jour:Swing JPanel ne pas repeindre

public void update(){ 
     GridBagConstraints constraints = new GridBagConstraints(); 

     if(cardsHidden){ 
      for(int i = 0; i < 2; i++){ 
       constraints.gridx = i; 
       constraints.gridy = 0; 
       JLabel card = new JLabel(PlayingCards.cardImages[PlayingCards.CARD_BACK_INDEX]); 
       add(card, constraints); 
      } 
     } 
     else{ 
      Card[] holeCards = player.getHoleCards(); 
      for(int i = 0; i < holeCards.length; i++){ 
       constraints.gridx = i; 
       constraints.gridy = 0; 
       JLabel card = new JLabel(holeCards[i].getImageIcon()); 
       add(card, constraints); 
      } 
     } 

     validate(); 
     repaint(); 
    } 

des idées?

Merci

EDIT

résolu:

Il se trouve que le HoleCardsPanel n'a pas été Rajouté à sa structure mère correctement. Une fois que cela a été corrigé l'ajout de nouveaux travaux de JLabel bien. J'ai aussi:

  • ajouté l'appel à la méthode update() au fil de l'envoi d'événement à l'aide SwingUtillities.invokeLater
  • dû appeler validate() du composant supérieur (dans ce cas, le JFrame) comme Devon_C_Miller suggests in his answer.

Répondre

0

Avez-vous essayé SetVisible() sur les étiquettes?

Avez-vous essayé d'ajouter les objets à l'initialisation sans aucune mise à jour? S'ils ne se présentent pas là, ils ne se montreront jamais.

+0

oui j'ai essayé cela, mais pas de chance :((mais je ne l'ai pas downvote) – Aly

+0

Ok. Personnellement, je suis en désaccord avec le downvote Les gens oublient généralement des choses simples comme ceci et cela peut résoudre le problème de quelqu'un d'autre –

+0

Je suis d'accord, donc je vais upvote pour l'annuler – Aly

12

Essayez d'appeler revalidate(); repeindre n'est pas ce que vous voulez.

Comme par:

API Docs

Remarque: Si un composant a été ajouté à un conteneur qui a été affiché, validate doit être appelée sur ce conteneur pour afficher la nouvelle composant. Si plusieurs composants sont en cours d'ajout, vous pouvez améliorer l'efficacité en appelant validation uniquement une fois, après que tous les composants aient été ajoutés. Revalidate() est fondamentalement un invalidate() suivi d'un validate().

Voir this question .....

+0

Je viens d'essayer de supprimer l'instruction repaint() et changé validate() à revalidate() mais pas de chance :( – Aly

+0

appelez-vous la mise à jour à partir d'un autre thread, ou le fil de distribution d'événement? –

+0

J'appelle mise à jour directement à partir d'un autre objet un fil standard – Aly

2

Vous pouvez essayer d'appeler la méthode updateUI().

20

Cela dépend de ce que vous voulez arriver et ce que les gestionnaires de mise en page sont utilisés, mais les règles de base sont:

  1. Assurez-vous update est appelé à l'EDT. Si ce n'est pas (SwingUtilities.isEventDispatchThread() renvoie false), vous devrez utiliser SwingUtilities.invokeLater pour planifier la mise à jour sur l'EDT. Par exemple:

    SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         update(); 
        }}); 
    
  2. Appel invalidate(). La plupart des choses qui changent un composant le feront pour vous. Vous n'avez donc besoin de l'appeler que si ce qui suit ne fonctionne pas seul.

  3. Appelez validate() sur le le plus haut composant affecté. C'est probablement le bit le plus boueux du cycle de rendu de Java. L'appel à invalidate marque le composant et tous ses ancêtres comme nécessitant une disposition. L'appel à validate exécute la disposition du composant et tous ses descendants . L'un fonctionne "en haut" et l'autre fonctionne "en bas". Vous devez appeler validate sur le composant le plus élevé dans l'arbre qui sera affecté par votre changement. Par ailleurs, l'appel d'une validation sur un composant de niveau supérieur (JWindow, JDialog, JFrame) ne redimensionnera pas nécessairement ce composant. Pour ce faire, vous devrez appeler pack() ou setSize(). Si vos modifications modifient la taille ou la position des conteneurs, les conteneurs redimensionnés seront repeints, mais ils n'effaceront pas l'espace occupé par le utilisé pour. En appelant le repaint() sur le parent du conteneur, il va repeindre l'arrière-plan, en corrigeant les dégâts.

+1

Où puis-je trouver une bonne ressource qui traite de toutes ces règles? Le Javadoc n'est pas explicite sur tout ce que vous avez écrit ci-dessus. Sûrement il y a une meilleure ressource ...? – Gili

0

Il se trouve que le HoleCardsPanel wansn't ajoutant à son cadre parent correctement, une fois qui a été corrigé l'ajout de nouvelles JLabels fonctionne très bien. J'ajouté appel à la méthode update() à l'aide de event dispatch threadSwingUtillities.invokeLater j'avais additionaly appeler validate() du composant supérieur (dans ce cas, le JFrame)

+1

Pensez à ajouter ces résultats à votre question pour référence future. – trashgod

Questions connexes