2017-06-01 112 views
1

我的程序需要一段時間才能加載,所以在加載時顯示加載窗口。然而,當我使用.show()時,我放入的加載指示器不旋轉,但由於某種原因,在使用.showAndWait()時會起作用。 我似乎無法弄清楚問題所在。這是調用加載窗口的控制器。JavaFX加載指示器顯示時未顯示動畫

package FX; 

import Utility.*; 
import javafx.collections.ObservableList; 
import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 

import java.io.IOException; 

/** 
* Created by Alex on 5/31/2017. 
*/ 
public class WindowController { 

@FXML private TextField startBox; 
@FXML private Button genButton; 
@FXML private ComboBox startPage; 
@FXML private ComboBox endPage; 
@FXML private GridPane grid; 
private Stage loadingStage; 
private Scene loadingScene; 

private Graph graph; 

@FXML 
public void initialize()throws IOException{ 
    AnchorPane pane = FXMLLoader.load(getClass().getResource("LoadingScreen.fxml")); 

    loadingScene = new Scene(pane); 
    loadingStage = new Stage(); 
    loadingStage.setTitle("Loading"); 
    loadingStage.setResizable(false); 
    loadingStage.setScene(loadingScene); 
    //loadingStage.initStyle(StageStyle.UTILITY); 
} 

@FXML 
public void GeneratePressed() throws IOException{ 
    loadingStage.show(); 
    String page = startBox.getText(); 
    graph = new Graph(page); 

    ObservableList<String> list = graph.getNamesList(); 
    startPage.setItems(list); 
    endPage.setItems(list); 
    loadingStage.close(); 
} 

@FXML void FindPathPressed(){ 

} 

public void dislayLoading(){ 

} 

} 

該窗口在GeneratePressed()中調用,並在初始化程序中創建。 另外,我試圖讓窗口導航欄爲不使用

loadingStage.initStyle(StageStyle.UTILITY); 

apear但似乎程序崩潰。

Finaly,這裏是我的FXML

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.ProgressIndicator?> 
<?import javafx.scene.layout.AnchorPane?> 
<?import javafx.scene.text.Font?> 
<?import javafx.scene.text.Text?> 


<AnchorPane maxHeight="180.0" maxWidth="250.0" minHeight="180.0" 
minWidth="250.0" prefHeight="180.0" prefWidth="250.0" 
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="FX.LoadingScreenController"> 
    <children> 
     <Text layoutX="87.0" layoutY="52.0" strokeType="OUTSIDE" 
strokeWidth="0.0" text="Loading" textAlignment="CENTER"> 
    <font> 
     <Font name="System Bold" size="20.0" /> 
    </font> 
    </Text> 
    <ProgressIndicator fx:id="load" layoutX="87.0" layoutY="74.0" 
prefHeight="72.0" prefWidth="76.0" /> 
    </children> 
</AnchorPane> 
+0

'GeneratePressed'大概是一個事件處理函數方法,所以它在FX應用程序線程上被調用。所以在FX應用程序線程可以做任何其他事情之前它會運行完成。因此,要麼'loadingStage.show()'和'loadingStage.close()'之間沒有足夠的時間來實際查看窗口,要麼阻止FX應用程序線程並阻止它呈現UI,這意味着您可以看不到窗戶。如果你有長時間運行的代碼,你需要在後臺線程上運行它。請參閱[API的文檔](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)。 –

回答

0

我使用這個加載我fxmls。您不需要fxml或者只有一個包含單個窗格。

/* 
* Loader for custom FXML on ScrollPane 
* You doesn't need the parameter, you can replace it 
* with your own fix path if you only load one view. 
*/ 
Task<Parent> loadFXML(String path) { 
    //Loader Task 
    Task<Parent> createMainScene = new Task<Parent>() { 
     @Override 
     public Parent call() { 
      //Update Message 
      updateMessage("Loading..."); 

      //Pane with FXML 
      Pane pane = null; 

      try { 
       // FXML loader 
       FXMLLoader loader = new FXMLLoader(); 

       // Set path to PARAMETERLISTE.fxml 
       loader.setLocation(getClass().getResource(path)); 

       // Set load fxml to Pane 
       pane = (Pane) loader.load(); 
      } catch (Exception e) { 
       System.err.println("Error. Grund: " + e.getMessage()); 
      } 

      //Return Pane 
      return pane; 
     } 
    }; 

    //ProgressBar 
    ProgressBar pBar = new ProgressBar(); 
    //Load Value from Task 
    pBar.progressProperty().bind(createMainScene.progressProperty()); 
    //Set PrefWidth 
    pBar.setPrefWidth(250); 
    //New Loading Label 
    Label statusLabel = new Label(); 
    //Get Text 
    statusLabel.textProperty().bind(createMainScene.messageProperty()); 
    //Set Style to Label 
    statusLabel.setStyle("-fx-font: 24 arial;"); 

    //Layout 
    VBox root = new VBox(statusLabel, pBar); 
    //SetFill Width TRUE 
    root.setFillWidth(true); 
    //Center Items 
    root.setAlignment(Pos.CENTER); 

    //Set Layout to ScrollPane 
    scrollpane.setContent(root); 

    //Display loaded FXML onSucceed 
    createMainScene.setOnSucceeded(e -> { 
     scrollpane.setContent(createMainScene.getValue()); 
    }); 

    //Start Thread 
    new Thread(createMainScene).start(); 

    return createMainScene; 
} 

也許這會幫助你。您可以設置自定義進度:

updateProgress([YOUR PROGRESS], [MAX VALUE]); 

要從其他梅索德使用訪問:

//Load yFXML 
    Task<Parent> task = loadFXML("/YOURFXML.fxml"); 
    //Set on Succeeded 
    task.setOnSucceeded(new EventHandler<WorkerStateEvent>() { 
     @Override 
     public void handle(WorkerStateEvent arg0) { 
      //Do your Stuff 

      //Set Scrollpane to new FXML 
      scrollpane.setContent(task.getValue()); 
     } 
    }); 

需要,因爲你的Java進一步運行,如果你不等待這個setOnSucceeded梅索德。這可以幫助