JavaFX如何改变阶段

Posted

技术标签:

【中文标题】JavaFX如何改变阶段【英文标题】:JavaFX how to change stage 【发布时间】:2012-10-11 18:49:15 【问题描述】:

我正在使用带有 Scene Builder 1.0 的 Netbeans 7.2 来开发 JavaFX 应用程序。我已经设置了主屏幕,我想拥有它,所以我单击一个按钮,它将关闭主窗口并打开另一个。主 Stage 对象位于主类中,但控制器类是独立的,并且无法访问它,因为它不是静态的并且在不同的类中。如何改变场景或舞台?

【问题讨论】:

【参考方案1】:

根据您的问题,最近我正在为 JavaFX 开发一个 ios 等效 NavigationController,使用推送和关闭视图的最简单想法。

让我把代码分享给社区:https://github.com/jalopezsuarez/javafx-screens

这个想法是有一个非常简单的环境来帮助您在屏幕之间切换。

希望对你有帮助。

【讨论】:

【参考方案2】:

我可能在这里说类似的话,但这就是我的做法:

(在此示例中,我正在从 Login.fxml 转换为 Home.fxml)。

在 LoginController.fxml 类中,我创建了以下方法:

@FXML
private void login(javafx.event.ActionEvent event) throws IOException

    if(pwf1.getText().equals("dolphin"))
    
            Parent blah = FXMLLoader.load(getClass().getResource("Home.fxml"));
            Scene scene = new Scene(blah);
            Stage appStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
            appStage.setScene(scene);
            appStage.show();
    
    else
    
            label1.setText("Password is incorrect. Please Try Again");
    

就是这样。;)

【讨论】:

【参考方案3】:

Download JavaFX samples 找到项目 FXML-LoginDemo ,这就是你需要的。为了快速参考,我在这里复制粘贴主要的 java 类;)

/*
 * Copyright (c) 2008, 2011 Oracle and/or its affiliates.
 * All rights reserved. Use is subject to license terms.
 *
 * This file is available and licensed under the following license:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the distribution.
 *  - Neither the name of Oracle Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package demo;

import demo.model.User;
import demo.security.Authenticator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 * Main Application. This class handles navigation and user session.
 */
public class App extends Application 
    private Stage stage;
    private User loggedUser;

    private static App instance;

    public App() 
        instance = this;
    

    public static App getInstance() 
        return instance;
    

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
        launch(args);
    

    @Override public void start(Stage primaryStage) 
        try 
            stage = primaryStage;
            gotoLogin();
            primaryStage.show();
         catch (Exception ex) 
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        
    

    public User getLoggedUser() 
        return loggedUser;
    

    public boolean userLogging(String userId, String password)
        if (Authenticator.validate(userId, password)) 
            loggedUser = User.of(userId);
            gotoProfile();
            return true;
         else 
            return false;
        
    

    public void userLogout()
        loggedUser = null;
        gotoLogin();
    

    private void gotoProfile() 
        try 
            replaceSceneContent("profile.fxml");
         catch (Exception ex) 
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        
    

    private void gotoLogin() 
        try 
            replaceSceneContent("login.fxml");
         catch (Exception ex) 
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        
    

    private Parent replaceSceneContent(String fxml) throws Exception 
        Parent page = (Parent) FXMLLoader.load(App.class.getResource(fxml), null, new JavaFXBuilderFactory());
        Scene scene = stage.getScene();
        if (scene == null) 
            scene = new Scene(page, 700, 450);
            scene.getStylesheets().add(App.class.getResource("demo.css").toExternalForm());
            stage.setScene(scene);
         else 
            stage.getScene().setRoot(page);
        
        stage.sizeToScene();
        return page;
    

【讨论】:

谢谢,这正是我想要的! 现在正确吗?我的意思是,我可以使用它并在 App 类之外调用 .replaceSceneContent 吗?或今天(2015 年)是否有正确的方法来进行阶段之间的更改?谢谢 =) 如何在 Controller 类中使用它?或者我可以只在主应用程序中使用它吗? 这个答案很旧,今天已经过时了:(【参考方案4】:

你也可以这样做:

这样修改你的controller.java

Stage thisStage;

public void setStage (Stage stage)
    thisStage = stage;


public void showStage()
    thisStage.setTitle("Titel in der MainController.java geändert");
    thisStage.show();

请务必不要在初始化方法中使用 thisStage。

以这种方式修改您的 Mainclass:

@Override
public void start(Stage stage) throws Exception 
    URL location = getClass().getResource("Main.fxml");
    FXMLLoader fxmlLoader = new FXMLLoader();
    fxmlLoader.setLocation(location);
    fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
    Parent root = (Parent) fxmlLoader.load(location.openStream());
    Scene scene = new Scene(root);
    stage.setScene(scene);
    MainController mainController = fxmlLoader.getController();
    mainController.setStage(stage);
    mainController.showStage();

您可以下载示例项目(netbeans)here。

【讨论】:

链接失效了,能不能再给一个?

以上是关于JavaFX如何改变阶段的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX:如何管理阶段的 z-index

如何从 JavaFX 中的 UI 控件中检索阶段

如何在一定时间后关闭一个阶段JavaFX

如何在 JavaFX 中获得一个阶段的关闭事件?

JavaFX:如何在初始化期间从控制器获取阶段?

如何在我的应用程序的javafx 2.0中更改阶段标题栏上的图标[重复]