2009-02-19 9 views
5

Ho una routine che dipinge un folle grafico all'interno di un riquadro di scorrimento. È troppo grande per dipingere prima di aggiungerlo alla pergamena: i requisiti menzionali sarebbero diversi.Perché il mio jscrollpane causa strani richiami di vernice in java swing?

A causa delle dimensioni del grafico, sto rendendo il grafico all'interno del metodo di disegno del figlio dello scrollpane. Funziona bene, tuttavia noto che ogni volta che una barra di scorrimento viene spostata, la mia routine di pittura viene chiamata due volte, una volta con un ritaglio uguale all'area scoperta a cui si scorre, e una seconda volta con il ritaglio uguale alle dimensioni della finestra. .

Per esempio, se la mia finestra è 245x195 & ho scorrere verso il basso da 3 pixel mia routine vernice viene chiamato con g.getClipBounds() insieme come segue:

java.awt.Rectangle[x=0,y=195,width=245,height=3] 
java.awt.Rectangle[x=0,y=3,width=245,height=195] 

... perché mi rendo all'interno della routine vernice questo sta causando lo sfarfallio (Faccio i miei calcoli il più velocemente possibile, ma credo che ci sia un po 'di ritardo). Domande:

  1. Qualcuno sa come evitare che la seconda chiamata di vernice? Questa è una semplice cosa JScrollPane che sto facendo qui - Ho un componente, lo aggiungo allo scrollpane, aggiungo lo scrollpane a un componente principale. Puoi vedere questo comportamento anche nella prima demo di scrolling delle immagini @the swing tutorial.

  2. Se la risposta al n. 1 è "no": qualcuno può pensare a un buon modo per affrontare questo? Dovrei dipingere su una sorta di buffer di immagini, tracciare le chiamate di vernice recenti & copiare l'immagine dove possibile? Non riesco a immaginare questo essere molto più veloce di re-rendering, ma tutta la comprensione apprezzato :-)

risposta

4

Ho incontrato questo problema nel mondo .NET. Il doppio buffering dovrebbe risolvere il tuo problema.

Se si esegue il rendering direttamente su una superficie che viene visualizzata sullo schermo, non si ha alcun controllo su quando il "mostrare" effettivamente accade. Ciò che in genere accade è: si avvia il rendering, l'immagine non ancora finita viene visualizzata sullo schermo, si finisce il rendering e questo viene finalmente visualizzato sullo schermo.

Se si avvia la logica di rendering cancellando il colore di sfondo, questo apparirà come un lampo. Il buffering doppio lo impedisce perché è sempre visualizzato da un rendering completato. Il peggio che potrebbe accadere è un leggero "strappo", ma questo è evidente solo nelle animazioni che cambiano rapidamente.

Anche se si desidera eseguire solo il rendering di parte di un'immagine gigantesca, è comunque possibile utilizzare questa tecnica. Rendi semplicemente ciò che ti serve su una superficie fuori dallo schermo (che è la dimensione della porzione visibile che desideri). E quando hai finito, disegna l'intera immagine sulla superficie dello schermo in un colpo solo.

+0

il mio unico problema è che non posso bufferizzare l'intera immagine - è troppo grande. Ciò significa che è necessario conservare le sezioni memorizzate nel buffer mentre vengono disegnate, verificare la copertura quando sono chiamato a dipingere() e cucirle insieme in base alle esigenze. Credo che darò uno sparo, ma mi terrò a bada per vedere se qualcun altro ha qualche idea –

+0

Bene, il doppio buffering può ancora entrare in gioco. Rendi semplicemente ciò che ti serve su una superficie fuori dallo schermo (la dimensione della porzione visibile). E quando hai finito, disegna l'intera immagine sulla superficie dello schermo in un colpo solo. – colithium

+0

in realtà, questo funziona.Grazie :-) Lo scorrimento è un po 'più lento, ma lo sfarfallio non c'è più. Scusa non l'ho capito @ prima - la mia stupidità non era all'altezza della tua perseveranza ;-) –