SwingWorker
SwingWorker är en populär [ enligt vem? ] verktygsklass utvecklad av Sun Microsystems för Swing -biblioteket i programmeringsspråket Java . SwingWorker möjliggör korrekt användning av händelseutsändningstråden . Från och med Java 6 ingår SwingWorker i JRE .
Flera inkompatibla, inofficiella versioner av SwingWorker producerades från 1998 till 2006, och försiktighet måste iakttas för att undvika den rikliga dokumentationen om dessa versioner som är före Java 6.
Användning i Java 6.0
Problemet med att skicka tråden för händelsen
SwingWorker är användbart när en tidskrävande uppgift måste utföras efter en användarinteraktionshändelse (till exempel tolka en enorm XML-fil, när du trycker på en JButton). Det enklaste sättet att göra det på är:
privat dokumentdokument ; _ ... JButton- knapp = ny JButton ( "Öppna XML" ) ; knappen . addActionListener ( ny ActionListener () { @Override public void actionPerformed ( ActionEvent e ) { doc = loadXML (); } });
Detta kommer att fungera, men tyvärr kommer metoden loadXML()
att anropas i samma tråd som Swing-huvudtråden ( händelseutsändningstråden ), så om metoden behöver tid att utföra kommer det grafiska gränssnittet att frysa under denna tid.
SwingWorker-lösning
Det här problemet är inte specifikt för Java, utan vanligt för många GUI- modeller. SwingWorker
föreslår ett sätt att lösa det genom att utföra den tidskrävande uppgiften på en annan bakgrundstråd, och hålla det grafiska användargränssnittet responsivt under denna tid.
Skapar arbetaren
Följande kod definierar SwingWorker, som kapslar in loadXML()
-metodanropet:
SwingWorker worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); returnera intDoc ; } };
Arbetares avrättning
Körningen startas genom att använda metoden SwingWorker.execute() .
Hämtar resultatet
Resultatet kan hämtas genom att använda metoden SwingWorker.get() .
Eftersom att anropa get()
på Event Dispatch Thread blockerar alla händelser, inklusive ommålningar, från att bearbetas tills uppgiften är klar, måste man undvika att anropa den innan den långa operationen har avslutats. Det finns två sätt att hämta resultatet efter att uppgiften är klar:
- åsidosätt metoden
SwingWorker.done() .
Den här metoden anropas på huvudhändelsens utsändningstråd .
privat dokumentdokument ; _ ... SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); returnera intDoc ; } @Override public void done () { try { doc = get (); } catch ( InterruptedException ex ) { ex . printStackTrace (); } catch ( ExecutionException ex ) { ex . printStackTrace (); } } }
- registrera en lyssnare genom att använda SwingWorker.addPropertyChangeListener(
PropertyChangeListener)
-metoden. Lyssnaren kommer att meddelas om ändringar i arbetartillståndet.
Komplett arbetarexempel
privat dokument doc ; ... JButton- knapp = ny JButton ( "Öppna XML" ) ; knappen . addActionListener ( new ActionListener () { @Override public void actionPerformed ( ActionEvent e ) { SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } @Override public void done () { try { doc = get (); } catch ( InterruptedException ex ) { ex . printStackTrace (); } catch ( ExecutionException ex ) { ex . printStackTrace (); } } }; arbetare .exekvera (); } }) ;
Historik: Användning före Java 6.0
SwingWorker har varit en del av Java SE endast sedan Java 6.0. Sun har släppt versioner för att användas med tidigare JDK, även om de var inofficiella versioner som inte var en del av Java SE och inte nämndes i standarddokumentationen för biblioteket. Den senaste av dessa versioner är från 2003 och kallas ofta för SwingWorker version 3. Tyvärr använder JDK 6.0 SwingWorker och Version 3 SwingWorker olika metodnamn och är inte kompatibla. Backportversionen (se nedan) rekommenderas nu för användning före Java 6.
Ett exempel för att instansiera SwingWorker 3 visas nedan:
SwingWorker worker = new SwingWorker () { public Object construct () { ... //add the code for the background thread } public void finished () { ... //kod som du lägger till här kommer att köras i UI-tråden } }; arbetare . start (); //Starta bakgrundstråden
start ()
exekverar koden som lagts till i metoden construct() i en separat tråd. För att bli varnad när bakgrundstråden är klar behöver man bara åsidosätta finished()-
metoden. Metoden construct()
kan returnera ett resultat som senare kan hämtas med SwingWorkers get()
-metod.
Backport för Java 6 SwingWorker
En backport av Java 6 SwingWorker till Java 5 är tillgänglig på http://swingworker.java.net/ [ permanent död länk ] . Förutom paketnamnet ( org.jdesktop.swingworker
) är det kompatibelt med Java 6 SwingWorker.
Motsvarigheter
-
System.ComponentModel.BackgroundWorker
- .NET Framework -
flash.system.Worker
- Adobe Flash -
android.os.AsyncTask
- Android
-
^
SwingWorker
-
^ Se
javax.swing
-paketsammanfattningen före och efter J2SE 6.0. Observera också att det inte finns någon SwingWorker-klass listad på indexsidorna i dokumentationen, fram till version 6.0: [ 1], [2] . - ^ Du kan ladda ner den "SwingWorker 3" . Internetarkiv. Arkiverad från originalet den 26 juni 2012.
externa länkar
- SwingWorker klass dokumentation för Java 7.
- Worker Threads och SwingWorker från Oracles handledning för Java Concurrency in Swing .
- Förbättra applikationsprestanda med SwingWorker i Java SE 6 av John O'Conner, januari 2007.