2016-01-18 59 views
0

我正在开发一个使用Java8和JavaFX的GUI应用程序。主窗口有一个应该打开新窗口的按钮(使用它自己的fxml)。到目前为止,我每次按下按钮时都会加载fxml,但由于新窗口中有很多控件,(令人惊讶的)需要一些时间(aprox 0.5-1s)来打开弹出窗口,因此我更改了代码以便主控制器在其初始化方法中加载弹出式fxml,并且只要按下按钮,预加载的窗口就会显示出来。 它一切正常,但现在我无法在新窗口上设置initOwner(...),因为我无法访问initilize方法中的窗口对象。我知道我不需要设置initOwner,但是我在开始菜单上有两个应用程序窗口(我想要避免)。任何想法如何解决这个问题? 另外,在JavaFX中显示新的窗口/对话框的标准方式是什么,每次事件发生时应该加载一个fxml,还是只显示/隐藏预加载的?如何在嵌套控制器中初始化对话窗口

回答

2

您可以在initialize()方法中加载一次FXML,然后在需要时懒惰地初始化对话窗口。即

public class Controller { 

    private Parent dialogPane ; 
    private Stage dialog ; 

    @FXML 
    private Button button ; 

    public void initialize() throws IOException { 
     dialogPane = FXMLLoader.load(getClass().getResource("dialog.fxml")); 
    } 

    @FXML 
    private void handleButtonPress() { 
     getDialog().show(); 
    } 

    private Stage getDialog() { 
     if (dialog == null) { 
      Scene scene = new Scene(dialogPane); 
      dialog = new Stage(); 
      dialog.setScene(scene); 
      dialog.initOwner(button.getScene().getWindow()); 
     } 
     return dialog ; 
    } 
} 
+0

我认为这是一个很好的方法,但这是正确的吗?我的意思是我认为它更好地加载FXML一次,而不是每次按下按钮时,对吧? – Stugal

0

您可以延迟加载fxml。

private Parent popupPane; 
private PopupPaneController popupPaneController; 

private void openPopup(ActionEvent event) { 
    if (popupPane == null) { 
     popupPane = FXMLLoader.load(...); 
     popupPaneController = // get it from FXMLLoader. Search this site for how 
    } 
    popupPaneController.updatePopupContent(newVals); 
    Stage popup = new Stage(); 
    popup.initOwner(primaryStage); 
    stage.setScene(new ScrollPane(popupPane)); 
    stage.show(); 
} 

注意,如果您缓存弹出窗口的内容,你可以设置initOwner()更高版本:当应用程序启动或不上的每个按钮的点击,但在请求时即不是。还可以检出Alert类作为弹出窗口的替代方法。请参阅examples of it

在显示预加载的场景/窗口时,您可能需要更新弹出窗口中显示的数据。为此在弹出控制器的类中实现一个updatePopupContent(newVals)方法,并在每个按钮单击时调用它,如上面的代码中所示。