2013-04-16 11 views
10

Sono nuovo con JavaFX e ho un piccolo problema con una discussione: posso eseguirlo due volte e non riesco a trovare il motivo.JavaFX: utilizzare una discussione più di una volta

Ecco una somma-UPT del mio codice:

Task<Void> task = new Task<Void>() { 
    @Override public Void call() throws ImageLoadedException, HomographyException, IOException { 
     try{ 
      System.out.println("GO !"); 
      return null; 
     } 
     catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return null; 
    } 
    @Override 
    protected void succeeded() { 
     super.succeeded(); 
     System.out.println("SUCCEEDED"); 
    } 
}; 

@FXML protected void launch(ActionEvent event){ 
    new Thread(task).start(); 
} 

Quando scatto una prima volta il tasto che avvia il mio thread, la mia corsa compito senza alcun problema (il mio display della console "GO!" E " SUCCESSO").

Ma se clicco una seconda volta, non aggiungo nulla. Sto facendo qualcosa di sbagliato ? Non possiamo usare una discussione più di una volta?

+1

No, non puoi usare una discussione più di una volta. – xagyg

risposta

11

Dalla documentazione Thread.start(): No

Non è mai legale per avviare una discussione più di una volta. In particolare, una discussione non può essere riavviata una volta completata l'esecuzione.

Dal Concurrency in JavaFX tutorial:

La classe Task definisce un oggetto una volta che non può essere riutilizzato. Se hai bisogno di un oggetto Worker riutilizzabile, usa la classe Servizio.

Quindi, è necessario considerare la classe Service anziché Task.


Modifica: questo dovrebbe funzionare per voi:

Service<Void> service = new Service<>(task); 

@FXML protected void launch(ActionEvent event){ 
    if (!service.isRunning()) { 
     service.reset(); 
     service.start(); 
    } 
} 
+0

Grazie mille per il vostro aiuto. Lo cercherò subito :) – SylCh

+0

Ricordati di impostare tu stesso l'esecutore e riutilizzalo o continui a creare nuovi thread ovunque. –

+0

@AndyTill puoi suggerire un approccio migliore? – tarrsalah

0

farlo con una classe wraper

  import java.io.IOException; 
      import javafx.concurrent.Task; 

      public class Executor { 
       private String name; 
       private Task<Void> task; 

       public Executor(final String name) { 
        this.name=name; 
        task = new Task<Void>() { 
         @Override 
         public Void call() throws IOException, InterruptedException { 
          try { 
           int i=0; 
           while(i<20){ 
            System.out.println(name); 
            Thread.sleep(2000); 
            i++; 
           } 
           return null; 
          } catch (IllegalThreadStateException e) { 
           System.out.println(e); 
          } 
          return null; 
         } 

         @Override 
         protected void succeeded() { 
          super.succeeded(); 
          try { 
           System.out.println(name+" finish"); 
          } catch (Exception ex) { 
           System.out.println(ex); 
          } 
         } 
        }; 
       } 

       public void start() { 
        try { 
           Thread th = new Thread(task); 
           th.start(); 
          } catch (Exception ex) { 
           System.out.println(ex); 
          } 
       } 
      } 
+0

come il tuo codice ti aiuta con la domanda? –

+1

È possibile eseguire l'attività tutte le volte che si desidera –

1

Con un pulsante può sparare nuovi compiti

    Button btn = new Button(); 
        btn.setText("New task"); 
        btn.setOnAction(new EventHandler<ActionEvent>() { 
         @Override 
         public void handle(ActionEvent event) { 
          Executor ex=new Executor("Task"+count); 
          ex.start(); 
          count++; 
          System.out.println("Task Starting..."); 
         } 
        }); 
Problemi correlati