2013-02-03 30 views
20

Tôi có một ứng dụng JavaFX 2 đơn giản, với 2 nút, bắt đầu và dừng. Khi nút bắt đầu được nhấp, tôi muốn tạo một chuỗi nền sẽ thực hiện một số xử lý và cập nhật giao diện người dùng (ví dụ: thanh tiến trình) khi nó chạy dọc. Nếu nút dừng được nhấp, tôi muốn chuỗi kết thúc.Đa luồng trong JavaFX treo giao diện người dùng

Tôi đã cố gắng thực hiện việc này bằng cách sử dụng lớp học javafx.concurrent.Task mà tôi thu thập từ tài liệu sẽ hoạt động tốt cho việc này. Nhưng bất cứ khi nào tôi nhấp vào Bắt đầu, giao diện người dùng bị treo/treo thay vì ở trạng thái bình thường.

cô là mã từ lớp học chính Myprogram extends Application cho hiển thị các nút:

public void start(Stage primaryStage) 
{    
    final Button btn = new Button(); 
    btn.setText("Begin"); 

    //This is the thread, extending javafx.concurrent.Task : 
    final MyProcessor handler = new MyProcessor(); 
    btn.setOnAction(new EventHandler<ActionEvent>() 
    { 
     public void handle(ActionEvent event) 
     {     
      handler.run(); 
     } 
    }); 

    Button stop = new Button(); 
    stop.setText("Stop"); 
    stop.setOnAction(new EventHandler<ActionEvent>() 
     { 
      public void handle(ActionEvent event) 
      { 
       handler.cancel(); 
      } 
     } 

    ); 
    // Code for adding the UI controls to the stage here. 
} 

Dưới đây là đoạn code của MyProcessor lớp:

import javafx.concurrent.Task; 
public class MyProcessor extends Task 
{ 
    @Override 
    protected Integer call() 
    { 
     int i = 0; 
     for (String symbol : feed.getSymbols()) 
     { 
      if (isCancelled()) 
      { 
       Logger.log("Stopping!"); 
       return i; 
      } 
      i++; 
      Logger.log("Doing # " + i); 
      //Processing code here which takes 2-3 seconds per iteration to execute 
      Logger.log("# " + i + ", DONE! ");    
     } 
     return i; 
    } 
} 

Khá đơn giản, nhưng giao diện người dùng bị treo bất cứ khi nào tôi bấm Start , mặc dù các thông báo trên bảng điều khiển vẫn tiếp tục được hiển thị (Logger.log chỉ đơn giản là System.out.println)

Tôi đang làm gì sai?

Trả lời

22

Task thực hiện Runnable, vì vậy khi bạn gọi handler.run();, bạn thực sự chạy phương thức call trong Chủ đề giao diện người dùng. Điều đó sẽ treo giao diện người dùng.

Bạn nên bắt đầu tác vụ trong chuỗi nền, qua trình xử lý hoặc chỉ đơn giản bằng cách gọi new Thread(handler).start();.

Điều này được giải thích (có thể không rõ ràng) trong the javadoc hoặc trong số JavaFX concurrency tutorial.

+3

Tôi không thể cảm ơn bạn đủ bạn đời. –

+0

Tôi có thêm một câu hỏi. Tôi muốn cập nhật một nhãn trong giao diện người dùng chính với tiến trình của chuỗi nhiệm vụ. Đối với điều này tôi sẽ sử dụng mã này trong nhiệm vụ: 'mainProg.updateStatus (i);', và trong chương trình chính: 'public void updateStatus (int i) {this.label.setText (i)); } '. Điều này có làm việc hay tôi nên sử dụng 'platform.runLater()' từ 'MainProg.updateStatus()' để cập nhật giao diện người dùng? –

+1

Có, bạn sẽ cần phải chạy nó trong UI Thread với runLater - Ngoài ra, bạn có thể sử dụng phương thức updateProgress (xem ví dụ 3 trong hướng dẫn) sẽ chạy trong thread UI. – assylias

Các vấn đề liên quan