2011-03-24 14 views
6

Come la maggior parte dei programmatori Java sanno, gli aggiornamenti a Swing GUI dovrebbe essere fatto solo sul thread evento AWT dispacciamento e la raccomandazione è che i processi di lunga esecuzione essere eseguite su un thread "lavoratore", con gli aggiornamenti inviati al thread di invio dell'evento utilizzando SwingUtilities.invokeAndWait() o SwingUtilities.invokeLater().modello per bloccare utente Java Swing nel thread di lavoro

Come si fa a fermare l'utente di procedere con l'applicazione, mentre il processo di lunga durata è completato? Disattivate i controlli e quindi riattivate il thread di lavoro utilizzando le chiamate SwingUtilities di cui sopra?

C'è una migliore modello alternativo?

+1

Perché avete necessità di vietare all'utente di utilizzare l'applicazione?Se possibile, vuoi evitare di farlo e permetti loro di andare avanti. Se è assolutamente necessario, tuttavia, che dire di una finestra di dialogo modale? Puoi anche disabilitare i controlli. – justkt

+0

Buona domanda. Non conosco nessuna risposta standard tranne il ProgressMonitor. – keuleJ

+0

@justkt: se il processo di lunga durata influisce sulla cosa che viene mostrata, potrei non volere che l'utente faccia qualcos'altro, tranne forse annullare l'operazione. Quello che faccio di solito è una finestra di dialogo modale con i pulsanti, ecc. Disabilitata tranne che per il pulsante "Annulla", ma spero in un modello più generale. – Ralph

risposta

3

vorrei prendere in considerazione 3 soluzioni:

  • disattivare i componenti del pannello: in genere è quello che faccio. Sfortunatamente, Swing non fornisce un modo semplice per disabilitare un pannello e tutti i suoi figli, ma è facile eseguire la ricorsione (vedere this other SO answer per quello). Un altro problema è che alcuni componenti Swing hanno lo stesso aspetto quando abilitati e disabilitati (JList, ad esempio)
  • nascondi il pannello con un CardLayout: in un pannello con un CardLayout, aggiungi 2 componenti. Il primo è il pannello che ospita i componenti da disattivare, mentre il secondo è un pannello che mostra un messaggio "loading" o "please wait". Un semplice JLabel in un Gridbaglayout fa il trucco. Quindi, devi solo passare da uno all'altro. Io uso questa tecnica per i luoghi in cui deve essere visualizzato un risultato di un calcolo/richiesta.
  • inserire un tipo di componente nella parte superiore del pannello che consuma gli eventi del mouse: è possibile farlo da soli con un LayeredPane oppure è possibile utilizzare un'utilità dedicata. JXLayer può farlo (ho letto che JXLayer sarà incluso in Java 7, quindi questa potrebbe diventare la soluzione "standard" per questo tipo di problema).
0

Un modo che ho visto fare è quello di utilizzare Jframe.setGlassPane() e impostare un componente che mangia tutti gli eventi. Puoi anche essere creativo e utilizzare il tipo di flash di gif di attesa rotazione nel tuo vetro. Ma nota che l'impostazione di un pannello di vetro potrebbe non essere tutto ciò che desideri. Per i requisiti più avanzati, potresti dover giocare con le code degli eventi.

2

Ci sono diversi modi e la cui selezione, in gran parte dipende dal design e il layout del vostro GUI.

  • Utilizzare una barra di avanzamento - Sostituire il pannello o su una superficie che non si desidera che un utente che tocca con una barra di avanzamento. Ciò ti impedirà di dover gestire eventi che non desideri ancora, rendendo comunque chiaro all'utente che qualcosa sta accadendo in background.
  • Disabilita i pulsanti e aggiungi un cursore di attesa - Usa setEnable (false) mentre il lavoro è in corso e nd eventualmente cambia il cursore in un Wait Cursor. Questo di nuovo chiarisce che un'opzione non è ancora disponibile solo per un periodo temporaneo.
  • Non rispondere agli eventi o lanciare un GlassPane - Questo è meno user-user in quanto rende l'applicazione non risponde, tuttavia può essere accettata in alcune situazioni.
Problemi correlati