2015-10-21 122 views
2

我想寫一個類來打開一個外部程序,做一個階段,說一個進度指示器「請稍候」,等待它完成,然後退出舞臺。如果我使用primaryStage.showAndWait();該程序可行,但如果我使用primaryStage.show();,程序將凍結,直到課程關閉纔會繼續。任何幫助將不勝感激。JavaFX - stage.show();在程序凍結結束

package application; 

import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.ProgressIndicator; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

import java.io.IOException; 


public class Wait { 
public static void display(String prog, String progPath){ 
    Stage primaryStage=new Stage(); 



    primaryStage.setTitle("Please Wait"); 
    primaryStage.setMinWidth(350); 

    ProgressIndicator indicator = new ProgressIndicator(); 

    Label label1=new Label(); 
    label1.setText("Please wait for "+prog+" to finish..."); 


    HBox layout=new HBox(20); 
    layout.getChildren().addAll(indicator, label1); 
    layout.setAlignment(Pos.CENTER); 
    layout.setPadding(new Insets(20,20,20,20)); 

    Scene scene =new Scene(layout); 
    primaryStage.setScene(scene); 

    primaryStage.show();// WHY U NO WORK?!?!?!?! 

    try { 

     Process p = Runtime.getRuntime().exec(progPath); 
     p.waitFor(); 


    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    primaryStage.close(); 

} 
} 
+0

是'Wait'用於JavaFX應用程序的主類? – ItachiUchiha

+0

@IchichiUchiha不,它是AM。等待只是一個我想打電話多次創建場景的課程。 – Techdroid

回答

2
假設

Wait.display()正在通過調用p.waitFor()在FX應用程序線程執行(這是需要的,因爲它產生並顯示一個Stage),代碼塊的FX應用程序線程。由於FX應用程序線程被阻止,因此無法執行任何常規工作,例如呈現UI或響應用戶輸入。

您需要在後臺線程中管理進程。使用Task將可以很容易地在FX應用程序線程執行代碼,一旦後臺進程已經完成:

public static void display(String prog, String progPath){ 
    Stage primaryStage=new Stage(); 

    primaryStage.setTitle("Please Wait"); 
    primaryStage.setMinWidth(350); 

    ProgressIndicator indicator = new ProgressIndicator(); 

    Label label1=new Label(); 
    label1.setText("Please wait for "+prog+" to finish..."); 

    HBox layout=new HBox(20); 
    layout.getChildren().addAll(indicator, label1); 
    layout.setAlignment(Pos.CENTER); 
    layout.setPadding(new Insets(20,20,20,20)); 

    Scene scene =new Scene(layout); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    Task<Void> task = new Task<Void>() { 
     @Override 
     public Void call() throws Exception { 

      try { 
       Process p = Runtime.getRuntime().exec(progPath); 
       p.waitFor();   
      } catch (IOException | InterruptedException e) { 
       e.printStackTrace(); 
      } 
      return null; 
    }; 

    task.setOnSucceeded(e -> primaryStage.close()); 

    Thread thread = new Thread(task); 
    thread.setDaemon(true); // thread will not prevent application from exiting 
    thread.start(); 
} 
+0

這很好。謝謝!請注意,在catch語句之後您確實需要'return null;'否則會出錯。 – Techdroid

+0

是的,對不起...修復它。 –