JavaFX как сменить сцену

Я использую Netbeans 7.2 с Scene Builder 1.0 для разработки приложения JavaFX. У меня есть мой главный экран, и я хочу его, поэтому я нажимаю кнопку, и он закрывает главное окно и открывает другое. Основной объект Stage находится в основном классе, но класс контроллера является отдельным и не может получить к нему доступ, поскольку он не является статичным и в другом классе. Как изменить сцену или сцену?

Ответ 1

Загрузите образцы JavaFX, найдите проект 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;
    }
}

Ответ 2

Вы также можете сделать это:

Измените ваш 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 в методе инициализации.

Измените свой основной класс следующим образом:

@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();
}

Вы можете скачать пример projekt (netbeans) здесь.

Ответ 3

Я, вероятно, говорю что-то похожее здесь, но вот как я это делаю:

(В этом примере я перехожу из 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");
    }
}

И что это.;)

Ответ 4

Исходя из вашего вопроса, недавно я работал над разработкой iOS-эквивалентного NavigationController для JavaFX, используя простейшую идею push и off-просмотров.

Позвольте мне поделиться кодом с сообществом: https://github.com/jalopezsuarez/javafx-screens

Идея состоит в том, чтобы иметь очень легкую среду, которая поможет вам переключаться между экранами.

Надеюсь, это поможет вам.