Domanda

Ho un'applet Java che utilizza AWT. In alcune (rare) circostanze, la piattaforma non aggiorna correttamente lo schermo. Posso spostare o ridurre a icona / ingrandire la finestra e vedere che la mia applet si è aggiornata correttamente. Sto cercando un codice che mi dia la massima riverniciatura dello schermo dell'applet possibile, simulando il comportamento di minimizzare / massimizzare.

Ho provato a chiamare varie combinazioni di paint () / repaint () / invalidate () / update () sui contenitori principali e a ricorrere su vari figli. Tuttavia, nessuna combinazione (che ho trovato) elimina i bug del framework che sto riscontrando. Sto cercando tecniche per aggiornare completamente l'applet, anche se possono causare un leggero sfarfallio, poiché invocherò questo codice solo sulla piattaforma problematica.

Nei miei test, passare a Swing non ha aiutato a risolvere il mio problema.

A proposito, questa è una semplificazione del mio precedente post (più complicato): Applet Java, problema di aggiornamento AWT Mac OS X 10.4

Modifica: l'indagine sul threading non ha risolto questo problema. Contrassegnare la migliore risposta come quella buona.

È stato utile?

Soluzione

Questo succede sempre se non stai programmando attentamente in AWT / Swing.

Prima di tutto, dovresti fare TUTTO il lavoro sul thread degli eventi. Ciò significa che non puoi fare nulla di tutto ciò nella tua dichiarazione principale (o in qualsiasi cosa chiami direttamente). So che ogni app della GUI Java mai inventata viola questa regola, ma questa è la regola.

Per lo più, dicevano che potevi usare un thread non awt fino a quando la finestra non era stata realizzata " (pack / setVisible), ma Sun ha capito che non sempre funzionava.

In secondo luogo, quando ricevi un evento sul thread AWT, assicurati di restituirlo rapidamente. Non dormire mai o eseguire un'operazione lunga.

Terzo, (e questa è un'estensione di " Primo " ;, se ricevi un callback che non è già sul thread di lavoro AWT, assicurati di inserirlo nel thread AWT prima di fare qualsiasi cosa con la GUI.

Generalmente, qualsiasi evento generato da un componente AWT sarà sul thread corretto. Gli eventi generati da timer, thread creati manualmente o quelli passati a main () non lo sono.

Altri suggerimenti

Il metodo da utilizzare per questo tipo di problema è ridipingere, come hai già detto. È possibile che tu stia riscontrando un problema con la JVM che stai utilizzando. Consiglio di utilizzare diverse versioni di Sun JVM e persino di MS VM per IE per vedere se si tratta di un problema relativo alla VM: potrebbe effettivamente non essere correlato al codice.

In realtà non l'ho mai provato prima, ma un modo creativo (cioè un brutto hack) potrebbe essere quello di eseguire javascript dall'applet per chiamare un metodo DOM per fare un ridimensionamento ridimensionato della finestra o forse chiamare focus su il corpo nel tentativo di provocare un ridisegno esterno della tela.

Non sono sicuro che ciò sia correlato a ciò che hai visto, ma se ti scontri con le prestazioni della coda eventi AWT, il mondo java 2d + 3d (gente della pipeline grafica) punterà in una strategia filettata e poi tu ' entrerò nel problema di smaltimento.

Questa discussione ha esaminato i progetti che utilizzano la coda degli eventi AWT per la grafica, come nell'uso di "ridipingere".

Nell'approccio con thread, c'è un problema di arresto.

Note in java / awt / SequencedEvent per " dispose " indicaci " Problemi di threading AWT " e "spegnimento automatico".

Sto pensando che questo bit di informazioni serva almeno a focalizzare il problema.

Sono stato in grado di risolvere il 99% dei miei problemi di ridisegno dell'applet AWT passando a Swing. Swing sembra essere più affidabile per rinfrescarsi.

In precedenza avevo molte ripetizioni manuali () nel mio codice dell'applet, ma con Swing queste sono state rimosse e l'applet è ora più veloce soprattutto in Terminal Server / LTSP.

Ho inserito elementi critici all'interno di questo:

public class VeryFastPanel extends JPanel {



    /**
         *
         */
        private static final long serialVersionUID = 1L;

        public void update(Graphics g) {

      paint(g);
    }

}

Ho riscontrato un problema che sembra essere lo stesso riscontrato. Dopo alcuni test, ho scoperto che questo può essere correlato agli adattatori grafici Aero e Intel. Nel mio caso, l'applicazione ha smesso di ridipingere solo se utilizzata in notebook senza adattatori CA, alimentata a batterie. Se si disabilitano alcune funzionalità di risparmio energetico nella configurazione del driver Intel (in particolare la tecnologia di visualizzazione Intel 2D nelle vecchie versioni dei driver) Java ridipingerà normalmente.

Nel mio caso ho trovato anche modi per disabilitare questa opzione tramite il registro. Non è documentato, ma funziona.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top