2012-02-06 39 views
9

Tôi muốn tải tối đa chín bảng trong một TilePane. Đối với mỗi cửa sổ, tôi phải chạy một tính toán của nội dung (khoảng 300ms) và thứ hai phải xây dựng Panel (khoảng 500ms). Những gì tôi muốn là, có chín ProgressIndicators mà trao đổi với mỗi bảng sau khi tính toán của nó. Tôi đã thử nó với lệnh Platform.runlater cũng như với một lớp dịch vụ. Kết quả luôn giống nhau. ProgressIndicator được hiển thị, nhưng không hoạt ảnh. Sau giây có tất cả các bảng cùng một lúc. Có khả năng nào, các chỉ số hoạt hình trong thời gian lỗ và tôi có thể trao đổi chúng cho nhau không?Thực hiện tác vụ ở chế độ nền trong JavaFX

Trả lời

11

JavaFX có Thread Dispatch Thread mà nó sử dụng cho các sự kiện UI. Tất cả công việc với giao diện người dùng sẽ xảy ra trên chuỗi này. Và tính toán không phải giao diện người dùng không nên xảy ra ở đó để tránh sự chậm trễ trong giao diện người dùng.

Xem mã tiếp theo:

public class Indicators extends Application { 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage stage) { 
     Pane root = new HBox(); 
     stage.setScene(new Scene(root, 300, 100)); 

     for (int i = 0; i < 10; i++) { 
      final ProgressIndicator pi = new ProgressIndicator(0); 
      root.getChildren().add(pi); 

      // separate non-FX thread 
      new Thread() { 

       // runnable for that thread 
       public void run() { 
        for (int i = 0; i < 20; i++) { 
         try { 
          // imitating work 
          Thread.sleep(new Random().nextInt(1000)); 
         } catch (InterruptedException ex) { 
          ex.printStackTrace(); 
         } 
         final double progress = i*0.05; 
         // update ProgressIndicator on FX thread 
         Platform.runLater(new Runnable() { 

          public void run() { 
           pi.setProgress(progress); 
          } 
         }); 
        } 
       } 
      }.start(); 
     } 

     stage.show(); 

    } 
} 
+0

Hi Sergey ... Tôi có một câu hỏi, tôi có thể có một số các chủ đề chạy trong ứng dụng ? Cảm ơn. –

+1

@MarcoR, chắc chắn, bạn có thể chạy 'Thread mới()' nhiều lần. –

+0

Cảm ơn Sergey, Bạn nên có một vài Platform.runLater trong ứng dụng ??. Vì các chủ đề này phải thay đổi chế độ xem, để exampe có hiển thị hộp thoại hay không. –

12

Đây là cách tôi giải quyết vấn đề:

import java.util.Random; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.concurrent.Service; 
import javafx.concurrent.Task; 
import javafx.concurrent.Worker; 
import javafx.concurrent.Worker.State; 
import javafx.geometry.Insets; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.ProgressBar; 
import javafx.scene.control.ProgressIndicator; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.TilePane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 


public class Minimal extends Application { 

private TilePane loadPane; 
private ProgressIndicator[] indicators = new ProgressIndicator[9]; 
private Label loading[] = new Label[9]; 
private Color[] colors = {Color.BLACK,Color.BLUE,Color.CRIMSON,Color.DARKCYAN,Color.FORESTGREEN,Color.GOLD,Color.HOTPINK,Color.INDIGO,Color.KHAKI}; 
private int counter = 0; 

@Override 
public void start(Stage primaryStage) throws Exception { 
    //creating Layout 
    final Group root = new Group();        
    Scene scene = new Scene(root, 400, 400);    
    primaryStage.setScene(scene); 
    primaryStage.setResizable(false); 
    StackPane waitingPane = new StackPane(); 
    final ProgressBar progress = new ProgressBar(); 
    Label load = new Label("loading things..."); 
    progress.setTranslateY(-25); 
    load.setTranslateY(25); 
    waitingPane.getChildren().addAll(new Rectangle(400,400,Color.WHITE),load,progress); 
    root.getChildren().add(waitingPane); 

    //Task for computing the Panels: 
    Task<Void> task = new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
      for (int i = 0; i < 20; i++) { 
       try { 
        Thread.sleep(new Random().nextInt(1000)); 
       } catch (InterruptedException ex) { 
        ex.printStackTrace(); 
       } 
       final double prog = i*0.05; 
       Platform.runLater(new Runnable() { 
        public void run() { 
         progress.setProgress(prog); 
        } 
       }); 
      } 
      return null; 
     } 
    }; 

    //stateProperty for Task: 
    task.stateProperty().addListener(new ChangeListener<Worker.State>() { 

     @Override 
     public void changed(ObservableValue<? extends State> observable, 
       State oldValue, Worker.State newState) { 
      if(newState==Worker.State.SUCCEEDED){ 
       loadPanels(root); 
      } 
     } 
    }); 

    //start Task 
    new Thread(task).start(); 

    primaryStage.show(); 
} 

private void loadPanels(Group root) { 
    //change to loadPanel: 
    root.getChildren().set(0,createLoadPane()); 

    //Service: 
    final Service<Rectangle> RecBuilder = new Service<Rectangle>() { 
      @Override protected Task<Rectangle> createTask() { 
       return new Task<Rectangle>() { 
        @Override protected Rectangle call() throws InterruptedException { 
         updateMessage("loading rectangle . . ."); 
         updateProgress(0, 10); 
         for (int i = 0; i < 10; i++) { 
         Thread.sleep(100); 
         } 
         updateMessage("Finish!"); 
         return new Rectangle((380)/3,(380)/3,colors[counter]); 
        } 
       }; 
      } 
    }; 

    //StateListener 
    RecBuilder.stateProperty().addListener(new ChangeListener<Worker.State>() { 
     @Override public void changed(ObservableValue<? extends Worker.State> observableValue, 
         Worker.State oldState, Worker.State newState) { 
      switch (newState) { 
      case SCHEDULED: 
       break; 
      case READY: 
      case RUNNING: 
       break; 
      case SUCCEEDED: 
       Rectangle rec = RecBuilder.valueProperty().getValue(); 
       indicators[counter].progressProperty().unbind(); 
       loading[counter].textProperty().unbind(); 
       loadPane.getChildren().set(counter, rec); 
       if(counter<8){ 
        counter++; 
        nextPane(RecBuilder); 
       } 
       break; 
      case CANCELLED: 
      case FAILED: 
       loading[counter].textProperty().unbind(); 
       loading[counter].setText("Failed!"); 
       if(counter<8){ 
        counter++; 
        nextPane(RecBuilder); 
       } 
       break; 
      } 
     } 
    }); 

    //begin PanelBuilding: 
    nextPane(RecBuilder); 
} 

private void nextPane(Service<Rectangle> recBuilder) { 
    loading[counter].textProperty().bind(recBuilder.messageProperty()); 
    indicators[counter].visibleProperty().bind(recBuilder.progressProperty().isNotEqualTo(new SimpleDoubleProperty(ProgressBar.INDETERMINATE_PROGRESS))); 
    recBuilder.restart(); 
} 

private Node createLoadPane() { 
    loadPane = new TilePane(5,5); 
    loadPane.setPrefColumns(3); 
    loadPane.setPadding(new Insets(5)); 
    for(int i=0;i<9;i++){ 
     StackPane waitingPane = new StackPane(); 
     Rectangle background = new Rectangle((380)/3, (380)/3, Color.WHITE); 
     indicators[i] = new ProgressIndicator(); 
     indicators[i].setPrefSize(50, 50); 
     indicators[i].setMaxSize(50, 50); 
     indicators[i].setTranslateY(-25); 
     indicators[i].setTranslateX(-10); 
     loading[i] = new Label(); 
     loading[i].setTranslateY(25); 
     waitingPane.getChildren().addAll(background,indicators[i],loading[i]); 
     loadPane.getChildren().add(waitingPane); 
    } 

    return loadPane; 
} 

public static void main(String[] args) { 
    launch(args); 
} 

} 
+0

Cảm ơn bạn. Tôi nghĩ rằng vấn đề là một nhiệm vụ (tốt hơn một nhiệm vụ duy nhất dụ) không thể chạy nhiều lần. Đặt thể hiện nhiệm vụ trong một phương thức mà chúng ta hãy khởi tạo lại nó bằng mọi lời gọi phương thức cũng đã giải quyết nó cho tôi. Tốt đẹp :) –

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