2013-04-16 37 views
10

Tôi là người mới với JavaFX và tôi có một vấn đề nhỏ với một chủ đề: Tôi có thể thực thi nó hai lần và tôi không thể tìm thấy lý do.JavaFX: Sử dụng một Chủ đề nhiều hơn một lần

Đây là một tổng hợp UPT mã của tôi:

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(); 
} 

Khi tôi bấm một lần đầu tiên vào nút người bắt đầu chủ đề của tôi, nhiệm vụ của tôi chạy mà không có vấn đề gì (giao diện điều khiển hiển thị của tôi "GO!" Và " SUCCEEDED ").

Nhưng nếu tôi nhấp lần thứ hai, không có gì thêm. Tôi có làm điều gì sai ? Chúng ta không thể sử dụng một chuỗi nhiều hơn một lần?

+1

Không, bạn không thể sử dụng một chuỗi hơn một lần. – xagyg

Trả lời

11

Từ các tài liệu Thread.start(): Không

Nó không bao giờ là pháp lý để bắt đầu một chủ đề nhiều hơn một lần. Cụ thể, một chủ đề có thể không được khởi động lại sau khi hoàn tất quá trình thực thi.

Từ Concurrency in JavaFX hướng dẫn:

Lớp công tác định nghĩa một đối tượng một lần mà không thể được tái sử dụng. Nếu bạn cần đối tượng Công nhân có thể sử dụng lại, hãy sử dụng lớp Dịch vụ.

Vì vậy, bạn phải xem xét lớp Service thay vì Task.


Sửa: điều này sẽ làm việc cho bạn:

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

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

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn. Tôi sẽ tìm kiếm điều đó ngay bây giờ :) – SylCh

+0

Hãy nhớ tự mình cài đặt và thực hiện lại hoặc bạn vẫn tạo chủ đề mới ở mọi nơi. –

+0

@AndyTill bạn có thể đề xuất một cách tiếp cận tốt hơn không? – tarrsalah

0

Làm điều đó với một lớp 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

mã của bạn giúp như thế nào với câu hỏi? –

+1

Bạn có thể chạy Tác vụ nhiều lần tùy ý –

1

Với một nút có thể bắn nhiệm vụ mới

    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..."); 
         } 
        }); 
Các vấn đề liên quan