Devi solo liberare il thread EDT di alcuni compiti pesanti e farli in un thread separato. In tal caso, l'animazione gif funzionerà insieme ad altri processi in esecuzione.
È inoltre possibile creare l'interfaccia dell'applicazione in un thread separato (sì sì, non all'interno dell'EDT) ma solo fino a quando non viene visualizzato. Successivamente è necessario apportare tutte le modifiche all'interno dell'EDT, altrimenti si potrebbero incontrare molti problemi.
È anche possibile caricare più elementi dell'interfaccia utente in un thread separato in seguito, ma assicurati di aggiungerli a frame/contenitori visualizzati all'interno di EDT: questa è la cosa più importante.
Ecco un piccolo esempio di interfaccia "heavy-like" di carico:
public static void main (String[] args) throws InvocationTargetException, InterruptedException
{
// Main window
final JFrame frame = new JFrame();
final JPanel panel = new JPanel (new FlowLayout (FlowLayout.LEFT, 5, 5))
{
public Dimension getPreferredSize()
{
Dimension ps = super.getPreferredSize();
ps.width = 0;
return ps;
}
};
frame.add (new JScrollPane (panel));
frame.setSize (600, 500);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo (null);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
frame.setVisible (true);
}
});
// Load dialog
final JDialog load = new JDialog (frame);
JPanel panel2 = new JPanel (new BorderLayout());
panel2.setBorder (BorderFactory.createEmptyBorder (15, 15, 15, 15));
load.add (panel2);
final JProgressBar progressBar = new JProgressBar (0, 100);
panel2.add (progressBar);
load.setModal (false);
load.pack();
load.setLocationRelativeTo (frame);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
load.setVisible (true);
}
});
// Heavy task (takes approx. 10 seconds + some time on buttons creation)
for (int i = 0; i < 100; i++)
{
Thread.sleep (100);
final JButton button = new JButton ("Button" + i);
final int finalI = i;
// Updating panel and progress in EDT
SwingUtilities.invokeLater (new Runnable()
{
public void run()
{
panel.add (button);
button.revalidate();
progressBar.setValue (finalI);
}
});
}
}
Come si può vedere - tutte le operazioni di aggiornamento dell'interfaccia sono realizzati in EDT, tutto il resto scorre dentro l'altro thread.
Si noti inoltre che il thread principale non è thread EDT, quindi possiamo fare qualcosa di pesante lì immediatamente.
In alcuni casi non è necessario visualizzare parti di interfaccia caricate subito, quindi è possibile aggiungerle tutte insieme alla fine dell'operazione "pesante". Ciò farà risparmiare tempo di caricamento e renderà il codice di inizializzazione molto più semplice.
Breve spiegazione su EDT e quello che ho detto nella risposta ...
...è stato qualcosa che ho trovato dopo aver lavorato per tre anni con Swing L & F e molte applicazioni basate su Swing. Ho scavato molte sorgenti Swing e ho trovato molte cose interessanti che non sono molto conosciute.
Come sapete - l'intera idea di singolo thread per gli aggiornamenti di interfaccia (la sua EDT in Swing) è di tenere ogni componente separato aggiornamenti visivi (ed i suoi eventi) in una coda ed eseguire uno per uno dentro quel filo . Ciò è necessario principalmente per evitare problemi di pittura poiché ogni componente all'interno di un singolo fotogramma viene dipinto sull'immagine singola che viene mantenuta in memoria. L'ordine di pittura è rigoroso, quindi un componente non sovrascriverà un altro sull'immagine finale. L'ordine di pittura dipende dall'albero dei componenti che viene creato aggiungendo alcuni componenti o contenitori all'interno di un altro contenitore (che è una cosa basilare che si fa quando si crea un'interfaccia dell'applicazione su Swing).
Per summ up - è necessario mantenere tutti i visivi aggiornamenti (metodi/operazioni che li potrebbero causare) all'interno del EDT. Qualsiasi altra cosa potrebbe essere eseguita al di fuori dell'EDT, ad esempio è possibile preparare l'interfaccia dell'applicazione all'esterno dell'EDT (anche in questo caso, a meno che non si aggiunga/rimuovi/sposti componente all'interno di un contenitore già visibile).
Ancora ci potrebbero essere alcuni problemi interni con quello in alcuni casi molto molto molto rari. C'è stata una buona discussione di tale questione un molto tempo fa qui:
http://www.velocityreviews.com/forums/t707173-why-does-jdk-1-6-recommend-creating-swing-components-on-the-edt.html
essere breve: dal 6 versione del JDK di Sun ha dichiarato nei documenti che anche Altalena creazione componenti dovrebbe essere fatto all'interno EDT per evitare possibili problemi. Potrebbero apparire in alcuni casi specifici con la creazione di interfacce pesanti a causa degli eventi che si verificano durante la creazione dei componenti.
In ogni caso, direi che in alcuni casi è possibile creare l'interfaccia esterna all'EDT per evitare che il caricatore/l'applicazione si blocchino. In altri casi, quando non importa se l'applicazione è bloccata per il tempo di creazione dell'interfaccia, è necessario utilizzare EDT. E non posso dire nulla di più specifico dal momento che tutto dipende dal tuo caso ...
considerare l'utilizzo di un [schermata di avvio] (http://docs.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html) invece se è per lo start-up della tua applicazione – Robin