2010-01-28 21 views
8

Tengo un objeto simple que se extiende JPanel, cuando se llama al método update() en este objeto, significaba agregar algunas etiquetas al panel y luego volver a pintar. Sin embargo, las etiquetas no se presenta después de que el método de actualización se llama, a continuación es el código para la actualización:Swing JPanel no volverá a pintar

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(); 
    } 

alguna idea?

Gracias

EDIT

resuelto:

Resulta que el HoleCardsPanel no fue añadiendo a su marco padre adecuadamente. Una vez que se arregló, la adición de la nueva JLabel s funciona bien. I también:

  • añadido la llamada al método update() a la rosca de distribución de eventos usando SwingUtillities.invokeLater
  • tuvo que llamar validate() desde el componente superior (en este caso el JFrame) como Devon_C_Miller suggests in his answer.

Respuesta

0

¿Has probado SetVisible() en las etiquetas?

¿Ha intentado agregar los objetos en la inicialización sin ninguna actualización? Si no aparecen allí, nunca aparecerán.

+0

sí lo ha intentado esto pero no hubo suerte :((pero no me downvote) – Aly

+0

Ok. Personalmente, no estoy de acuerdo con la votación negativa. La gente generalmente olvida cosas simples como esta y esto puede resolver el problema de otra persona. –

+0

Acepto, por lo tanto, votaré para cancelarlo – Aly

12

Intenta llamar a revalidate(); volver a pintar no es lo que quieres.

Según:

API Docs

Nota: Si un componente ha sido añadido a un contenedor que se ha mostrado, de validación debe ser llamado en ese contenedor para mostrar el nuevo componente. Si se agregan varios componentes , puede mejorar la eficacia de llamando solo validar una vez que se hayan agregado todos los componentes .

revalidate() es básicamente un invalidate() seguido de un validate().

Ver this pregunta .....

+0

Acabo de tratar de eliminar la instrucción repaint() y he cambiado validate() para revalidar() pero no tuve suerte :( – Aly

+0

¿Estás llamando a la actualización de otro hilo, o el hilo de envío del evento? –

+0

Estoy llamando a la actualización directamente desde otro objeto que se ejecuta un hilo estándar – Aly

2

Puede intentar llamar al método updateUI().

20

Depende de lo que queremos que suceda y lo que los gerentes de diseño están en uso, pero las reglas básicas son:

  1. Asegúrese update se llama en la EDT. Si no es así (SwingUtilities.isEventDispatchThread() devuelve falso) deberá usar SwingUtilities.invokeLater para programar la actualización en el EDT. Por ejemplo:

    SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         update(); 
        }}); 
    
  2. llamada invalidate(). La mayoría de las cosas que cambian un componente lo harán por ti. Entonces solo necesita llamar a esto si lo siguiente no funciona por sí mismo.

  3. Llamada validate() en el componente más afectado. Este es probablemente el bit más oscuro del ciclo de renderizado de Java. La llamada a invalidate marca el componente y todos sus antecesores como necesarios. La llamada al validate realiza el diseño del componente y todos sus descendientes. Uno funciona "arriba" y el otro funciona "abajo". Debe llamar al validate en el componente más alto del árbol que se verá afectado por su cambio.

    Además, llamar para validar en un componente de nivel superior (JWindow, JDialog, JFrame) no necesariamente cambiará el tamaño de ese componente. Para que esto suceda, deberá llamar al pack() o al setSize().

  4. Si sus cambios alteran el tamaño o la posición de los contenedores, los contenedores redimensionados se volverán a pintar, pero no borrarán el espacio que utilizó para ocupar. Llamar al repaint() en el elemento primario del contenedor causará que vuelva a pintar el fondo, corrigiendo el daño.

+1

¿Dónde puedo encontrar un buen recurso que discuta todas estas reglas? El Javadoc no es explícito sobre todo lo que escribió arriba. Sin duda hay un recurso mejor ...? – Gili

0

Resulta que el HoleCardsPanel wansn't añadiendo a su marco padre adecuadamente, una vez que se haya previsto la adición de nuevos JLabels funciona bien. Yo añadido llamada al método update() a la event dispatch thread usando SwingUtillities.invokeLater que adicionalmente que llamar validate() del componente superior (en este caso el JFrame)

+1

Considere agregar estos resultados a su pregunta para referencia futura. – trashgod

Cuestiones relacionadas