2011-01-09 14 views
5

Ho un JPanel all'interno di una cornice. I contenuti di JPanel dovrebbero essere aggiornati con ogni chiamata a paintComponent (che è chiamata da repaint()), ma quando lo faccio come di seguito, vedo solo una finestra bianca. (scusate il rientro straziati, Eclipse non tutti i tipi di cose strane con le schede.)Ridipingere un JPanel all'interno di una cornice

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

In realtà, Eclipse fa tutti i tipi di cose interessanti con le schede. :-) Basta premere CTRL-SHIFT-F per formattare la fonte automaticamente. Produrrà una formattazione e una rientranza coerenti per te, alleviandoti dall'onere di farlo da solo. – harschware

+0

quali sono i valori per x (0), y (0)? L'immagine potrebbe essere al di fuori del tuo pannello. Lo esegui in un debugger? Il codice può generare un'eccezione nel thread della GUI se l'immagine non viene trovata. – josefx

risposta

6

Hai diversi problemi con il tuo codice, uno è stato menzionato sopra (1+ rappresentante - anche se mi sembra che tu abbia il codice ora nel tuo metodo paintComponent che fa il disegno), il tuo metodo paintComponent è imperfetto, ma non solo, hai un ciclo while (vero) e un Thread.sleep nel thread principale di Swing, l'EDT, che metterà in pausa Swing e l'intera GUI. Meglio usare un timer Swing. Inoltre, dichiarate,

Il contenuto delle JPanel dovrebbero essere aggiornati con ogni chiamata a paintComponent (che è chiamato da repaint()),

Sei sicuro che si desidera mettere logica di programma all'interno del metodo paintComponent? Questo di solito è disapprovato dal momento che il programmatore non ha il controllo completo su quando viene chiamato questo metodo. Può essere chiamato quando si chiama repaint (ma non sempre), e può essere chiamato a causa di messaggi dal sistema operativo quando non si prevede che venga chiamato.

Inoltre, non si desidera leggere un file all'interno del metodo paintComponent in quanto ciò rallenterà il disegno su un nottolino.

mi consiglia di questi cambiamenti:

1) creare un timer swing con un periodo di 1000, e nel suo metodo actionPerformed di ActionListener, leggere nell'immagine (preferibilmente in un thread in background, se l'immagine ha alcuna significativa dimensione) e fare in modo che l'immagine venga letta in un campo classe, ad esempio immagine.

2) Nello stesso modo di esecuzione del timer, metodo eseguito, incremento t.

3) Dopo aver letto l'immagine, richiamare il disegno sul JPanel e fare in modo che il disegno JPanel utilizzi la variabile dell'immagine per dipingere l'immagine con. Fai attenzione se stai usando un thread in background per leggere nell'immagine, poiché avrai bisogno che questo thread notifichi la GUI quando l'immagine è stata completamente letta. Se usi uno SwingWorker per farlo, puoi aggiungere un PropertyChangeListener che ascolta al valore dello stato di SwingWorker e si innesca quando questo cambia in StateValue.DONE.

Se uno di questi non è chiaro o confuso, si prega di chiedere chiarimenti.

modifica: se le immagini non sono troppo grandi, si consiglia di leggerle tutte in una volta o di eseguire una lettura batch quando è necessario un mazzo. Non c'è assolutamente bisogno di leggere le immagini immediatamente prima di usarle.

1

tua paintComponent solo chiamate super.paintComponent. Quindi JPanel mentre dipingi te stesso, che sarà grigio chiaro, o bianco o marrone chiaro o qualcosa che dipende dal tuo aspetto.

+0

Probabilmente è bianco perché la sua app si è bloccata quando è andato a dormire e non ha completato tutti i rifacimenti. – harschware

2

Non interrompere il thread. Utilizzare un timer Swing per disattivare gli eventi di ridisegno.