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:

  

       
    
       
           
         
    
    
       
         
              
            
            
            
            
        
    
 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

  1. ^ SwingWorker
  2. ^ 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] .
  3. ^ Du kan ladda ner den "SwingWorker 3" . Internetarkiv. Arkiverad från originalet den 26 juni 2012.

externa länkar