2011-01-09 16 views
5

Tengo un JPanel dentro de un marco. Se supone que los contenidos de JPanel se actualizan con cada llamada al paintComponent (que se llama por repaint()), pero cuando lo hago como se muestra a continuación, simplemente veo una ventana blanca. (Por favor, disculpe la sangría destrozado, Eclipse hace todo tipo de cosas raras con pestañas.)Repainting un JPanel dentro de un marco

private static void handleGUI() 
{  
    JFrame frame = new JFrame("Animation"); 
    frame.setPreferredSize(new Dimension(100, 100)); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Board b = new Board(); 

    frame.getContentPane().add(b); 

    frame.pack(); 
    frame.setVisible(true); 

    while(true) 
    { 
     System.out.println("Repainting panel"); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
     } 
     b.repaint(); 
    } 
} 

public class Board extends JPanel 
{ 
public Board() { t=0; } 

    private int t; 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 

    ++t; 

    /* Variables snipped */ 

    g.setColor(Color.white); 
    g.drawOval(0, 0, width, height); 

    BufferedImage image = ImageIO.read(new File(imagePath)); 
    g.drawImage(image, x(t), y(t)); 
    /* There's some more image and rectangle drawing ahead */ 
} 

}

+2

En realidad, Eclipse hace todo tipo de cosas interesantes con pestañas. :-) Simplemente presiona CTRL-SHIFT-F para formatear tu fuente automáticamente. Producirá un formato y sangría consistentes para usted, liberándole de la carga de hacerlo usted mismo. – harschware

+0

¿Cuáles son los valores para x (0), y (0)? La imagen podría estar fuera de su panel. ¿Lo ejecuta en un depurador? El código puede arrojar una excepción en el hilo de la GUI si no se encuentra su imagen. – josefx

Respuesta

6

Tiene varios problemas con su código, uno ha sido mencionado anteriormente (1+ rep, aunque me parece que tiene código ahora en su método paintComponent que sí lo hace), su método paintComponent es defectuoso, pero no solo eso, tienes un ciclo while (verdadero) y un Thread.sleep en el hilo principal Swing, el EDT, que pondrá a dormir a Swing y a toda tu GUI. Es mejor usar un temporizador de oscilación en su lugar. También, usted afirma,

Se supone que los contenidos de los JPanel que ser actualizado con cada llamada a paintComponent (que es llamada por repinte()),

¿Estas seguro que quieres poner lógica de programa dentro del método paintComponent? Esto generalmente no está bien visto ya que usted, el programador, no tiene control absoluto sobre cuándo se llama este método. Se puede invocar cuando se llama a volver a dibujar (pero no siempre), y se puede invocar debido a los mensajes del sistema operativo cuando no se espera que se llame.

Además, nunca querrá leer un archivo dentro del método paintComponent, ya que esto reducirá la velocidad de la pintura a un triscado.

te recomiendo estos cambios:

1) crear un temporizador oscilación con un período de 1000, y en su método actionPerformed de ActionListener, leído en su imagen (preferentemente en un subproceso de fondo si la imagen tiene ninguna significativa tamaño) y hacer que la imagen se lea en un campo de clase, por ejemplo, llamada imagen.

2) En el mismo método Timer actionPerformed, incremente t.

3) Después de que la imagen haya sido leída, llame a repintar sobre el dibujo JPanel y haga que el dibujo JPanel use la variable de imagen para pintar la imagen. Tenga cuidado si está utilizando un hilo de fondo para leer en la imagen, ya que necesitará que este hilo notifique a la GUI cuando la imagen se haya leído por completo. Si utiliza un SwingWorker para hacerlo, puede agregar un PropertyChangeListener que escuche al valor de estado de SwingWorker y se activa cuando esto cambia a StateValue.DONE.

Si algo de esto no está claro o es confuso, solicite una aclaración.

editar: si las imágenes no son demasiado grandes, es posible que desee leerlas todas a la vez, o hacer una lectura por lotes cuando se necesiten varias. No hay necesidad absoluta de leer en las imágenes inmediatamente antes de usarlas.

1

su paintComponent sólo llama super.paintComponent. Entonces, el JPanel mientras se pinta, que será de color gris claro, o blanco o marrón claro o algo dependiendo de su apariencia.

+0

Probablemente sea blanco porque su aplicación se bloqueó cuando se durmió y no terminó todas las reparaciones. – harschware

2

No hagas que el hilo duerma. Use un temporizador de oscilación para activar los eventos de repintado.

Cuestiones relacionadas