Сцена изменения javafx

Я новичок в javaFX и имею представление о java на начальном уровне. Я пытаюсь создать простое приложение, которое в конечном итоге будет генерировать формы. Я хочу изменить сцены, когда кнопка нажата, но я не знаю, как это сделать, все, что я прочитал, немного выше моего уровня.

@Override
public void start(Stage primaryStage) {

         primaryStage.setTitle("Welcome to the Log Book Generator");
         /*Defining Options on Home screen*/

         Button btnR = new Button("Repair");
         Button btnM = new Button("Maintenance");
         Button btnW = new Button("Weather");
         Button btnO = new Button ("Other");
         Button btnU = new Button ("Filter Pickup");
         Button btnVC = new Button ("Verification/Calibration");
         Button btnE = new Button ("Exit");



    /*Actions upon button selection*/    
    btnR.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Repair");
        }
    });
    btnM.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Maintenance");
        }
    });
    btnW.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Weather");
        }
    });
    btnO.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Other");
        }
    });
    btnU.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Filter Pickup");
        }
    });
    btnVC.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Verification/Calibration");
        }
    });
    btnE.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.exit(0);
        }
    });
    Pane root = new Pane();
    /*StackPane root = new StackPane();
    /* Setting Button Layout*/
    btnM.setLayoutX(150);btnM.setLayoutY(150);
    btnR.setLayoutX(150);btnR.setLayoutY(250);
    btnW.setLayoutX(150);btnW.setLayoutY(350);
    btnO.setLayoutX(150);btnO.setLayoutY(150);
    btnU.setLayoutX(150);btnU.setLayoutY(450);
    btnVC.setLayoutX(150);btnVC.setLayoutY(550);
    btnE.setLayoutX(350);btnE.setLayoutY(650);
    /*Ask user for Selection*/
    Label label;
    label = new Label("Please select a task.");
    label.setFont(Font.font("Arial", 32));            
    root.getChildren().add(label);
    root.getChildren().add(btnE);
    root.getChildren().add(btnVC);
    root.getChildren().add(btnU);
    root.getChildren().add(btnO);
    root.getChildren().add(btnW);
    root.getChildren().add(btnM);
    root.getChildren().add(btnR);
    primaryStage.setScene(new Scene(root, 500, 750));
    primaryStage.show();
}

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

} ` Я планирую сделать разные части отдельной сценой на одной сцене. Любая помощь будет оценена по достоинству. Я использую NetBeans8.2.

stackoverflow.com/questions/37200845/…
Sedrick 13.09.2018 23:11

Не использовать FXML, поэтому этот ответ не помогает. Я не передаю данные между сценами, поэтому не понимаю, зачем мне использовать FXML.

Michael H. 14.09.2018 00:24

Что общего между передаваемыми данными и fxml?

Sedrick 14.09.2018 00:40

Создайте сцену в каждом обработчике, а затем используйте primaryStage.setScene ()

Sedrick 14.09.2018 00:41

Из большей части того, что я читал, FXML предназначен для передачи данных.

Michael H. 14.09.2018 00:49

Седрик, можешь показать мне пример?

Michael H. 14.09.2018 00:50

Scene, насколько я понимаю, влияет на весь Stage, а не только на его части. Если вы хотите заменить определенные части окна при нажатии кнопки, вы захотите использовать другие контейнеры, а не сцены.

Zephyr 14.09.2018 01:17

На несвязанном примечании: FXML действительно не имеет ничего общего с передачей данных. Это структура, используемая для определения макета графического интерфейса приложения. Часто это может упростить процесс разработки и обновления пользовательского интерфейса для вашего приложения. В сочетании со SceneBuilder это может быть отличным способом разработки вашего приложения, поскольку вы можете мгновенно увидеть результаты без необходимости компилировать и запускать код.

Zephyr 14.09.2018 01:47

Еще одно замечание: вы слишком много работаете, чтобы расположить кнопки там, где вы хотите. Проведите дополнительное исследование контейнеров JavaFX. В частности, похоже, что VBox был бы для вас намного лучше, чем StackPane.

Zephyr 14.09.2018 01:51
0
9
3 574
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

вы можете создавать свои сцены, инициализировать их и устанавливать их на основной этап в обработчиках событий, просто обратите внимание, что если вы пытаетесь добавить дочерние элементы друг над другом по вертикали, вам следует рассмотреть возможность использования VBox, также если вы хотите добавить несколько дочерних элементов в один и тот же родительский элемент, вы можете использовать addAll вместо добавления

это код, который у вас будет (я только что сделал первые 3 сцены, чтобы показать вам, как это работает, и вы должны иметь возможность делать другие соответственно)

// having a fixed size for the stage
double width = 500, height = 600;

// Creating scenes
Scene sceneR, sceneM, sceneW, sceneO, sceneU, sceneVC, mainMenu;

// saving the primaryStage to have access to it from other methods
Stage ps;

@Override
public void start(Stage primaryStage) {
    ps = primaryStage;

    //calling the initializing method
    initializeScenes();

    primaryStage.setTitle("Welcome to the Log Book Generator");
    /* Defining Options on Home screen */

    Button btnR = new Button("Repair");
    Button btnM = new Button("Maintenance");
    Button btnW = new Button("Weather");
    Button btnO = new Button("Other");
    Button btnU = new Button("Filter Pickup");
    Button btnVC = new Button("Verification/Calibration");
    Button btnE = new Button("Exit");

    /* Actions upon button selection */
    btnR.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneR);
        }
    });
    btnM.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneM);
        }
    });
    btnW.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneW);
        }
    });
    btnO.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Other");
        }
    });
    btnU.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Filter Pickup");
        }
    });
    btnVC.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Verification/Calibration");
        }
    });
    btnE.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.exit(0);
        }
    });

    // 20 will be the spacing
    VBox root = new VBox(40);
    root.setAlignment(Pos.CENTER);

    Label label;
    label = new Label("Please select a task.");
    label.setFont(Font.font("Arial", 32));

    // Adding buttons to the root
    root.getChildren().addAll(label, btnR, btnM, btnW, btnO, btnU, btnVC, btnE);

    btnE.setTranslateX(100);

    mainMenu = new Scene(root, width, height);
    primaryStage.setScene(mainMenu);
    primaryStage.show();
}

public void initializeScenes() {
    // You Can Here Add Whatever you want into your scenes

    // initializing the Repair Scene :

    VBox rootR = new VBox(10);
    rootR.setAlignment(Pos.CENTER);
    Label descR = new Label("Repair Scene");
    Button backR = new Button("back");
    rootR.getChildren().addAll(descR, backR);
    // the back button takes you back to the main menu scene
    backR.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneR = new Scene(rootR, width, height);

    // initializing the Maintenance Scene :

    VBox rootM = new VBox(10);
    rootM.setAlignment(Pos.CENTER);
    Label descM = new Label("Maintenance Scene");
    Button backM = new Button("back");
    rootM.getChildren().addAll(descM, backM);
    // the back button takes you back to the main menu scene
    backM.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneM = new Scene(rootM, width, height);

    // initializing the Weather Scene :

    VBox rootW = new VBox(10);
    rootW.setAlignment(Pos.CENTER);
    Label descW = new Label("Weather Scene");
    Button backW = new Button("back");
    rootW.getChildren().addAll(descW, backW);
    // the back button takes you back to the main menu scene
    backW.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneW = new Scene(rootW, width, height);



    // you should be able to do the other scenes
}

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

Сцены заменять довольно редко - новичка угловыми случаями лучше не кормить ... просто говорю ..

kleopatra 14.09.2018 10:01
Ответ принят как подходящий

Вместо того, чтобы пытаться изменить Scene, похоже, вы просто хотите обновить части экрана.

Ниже приведен простой пример использования BorderPane для корневого макета и последующего изменения содержимого панели CENTER при нажатии кнопки.

В приведенном ниже примере просто переключается содержимое для разных этикеток, но вы также можете легко использовать root.setCenter() для передачи всего VBox или HBox или любого другого заполненного контейнера.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    private BorderPane root;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setWidth(500);

        // Simple interface. The buttons will be on the left and the contents of the center section will change
        // when buttons are clicked.
        root = new BorderPane();
        root.setPadding(new Insets(10));

        // Create the left pane, containing buttons to switch the CENTER content
        VBox paneButtonBox = new VBox(5);
        paneButtonBox.setAlignment(Pos.TOP_CENTER);
        paneButtonBox.setPadding(new Insets(10));

        // Create 3 buttons to change the contents of the CENTER
        Button btnView1 = new Button("View 1");
        btnView1.setOnAction(e -> switchContent(1));
        Button btnView2 = new Button("View 2");
        btnView2.setOnAction(e -> switchContent(2));
        Button btnView3 = new Button("View 3");
        btnView3.setOnAction(e -> switchContent(3));

        // Add the Buttons to the button box
        paneButtonBox.getChildren().addAll(btnView1, btnView2, btnView3);

        // Add the button box to the LEFT of root pane
        root.setLeft(paneButtonBox);

        primaryStage.setScene(new Scene(root));

        primaryStage.show();
    }

    /**
     * @param view is the # of the content we want to display. For this sample, just to demonstrate.
     */
    private void switchContent(int view) {

        // Change the content of the CENTER node based on button clicked
        switch (view) {
            case 1:
                root.setCenter(new Label("THIS IS VIEW 1"));
                break;
            case 2:
                root.setCenter(new Label("THIS IS VIEW 2"));
                break;
            case 3:
                root.setCenter(new Label("THIS IS VIEW 3"));
                break;

        }

    }
}

Приведенный выше код создает следующий макет:

Screenshot

Label справа изменяется при нажатии каждой кнопки. Надеюсь, это поможет вам в правильном направлении.

Основная идея состоит в том, чтобы создать часть вашего макета, содержимое которой вы можете изменять. BorderPane предоставляет эти разделы для вас, но вы также можете просто создать отдельный VBox самостоятельно и просто вызвать VBox.getChildren().addAll() и передать любые объекты Node, которые вы хотите, когда вам нужно изменить содержимое.

Another Option

Другой способ реализовать подобную функциональность интерфейса - использовать TabPane. Каждый Tab, который вы добавляете к TabPane, имеет свойство content, которое вы можете использовать для установки любых узлов по вашему выбору, подобно тому, как BorderPane работает выше:

@Override
public void start(Stage primaryStage) {

    primaryStage.setHeight(300);
    primaryStage.setWidth(500);

    TabPane root = new TabPane();

    // Create Separate Tabs
    Tab tab1 = new Tab("Section 1");
    tab1.setContent(new Label("This is Section 1!"));
    Tab tab2 = new Tab("Section 2");
    tab2.setContent(new Label("This is Section 2!"));
    Tab tab3 = new Tab("Section 3");
    tab3.setContent(new Label("This is Section 3!"));

    root.getTabs().addAll(tab1, tab2, tab3);

    primaryStage.setScene(new Scene(root));
    primaryStage.show();

}

И вот результат:

Screenshot

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

Lukas Owen 14.09.2018 01:50

Цените голос за. OP является новичком в Java и кажется немного сбитым с толку, поскольку он конкретно говорит, что хочет изменить только часть сцены. Замена Scene, очевидно, повлияет на весь Stage. Я определенно согласен, что на данный момент лучше всего иметь оба ответа, поскольку несколько неясно, чего действительно хочет OP.

Zephyr 14.09.2018 01:52
package principal;

public class Start extends Application {

    private static Stage stage;

    private static Scene parametrizacao;
    private static Scene monitorar;
    private static Scene relatorio;

    @Override
    public void start(Stage primaryStage) throws Exception {
        stage = primaryStage;

        primaryStage.setTitle("Java FX");

        Parent fxmlInicio = FXMLLoader.load(getClass().getResource("/fxml/inicio.fxml"));
        parametrizacao = new Scene(fxmlInicio);

        Parent fxmlMonitorar = FXMLLoader.load(getClass().getResource("/fxml/monitora.fxml"));
        monitorar = new Scene(fxmlMonitorar);

        Parent fxmlRelatorio = FXMLLoader.load(getClass().getResource("/fxml/relatorio.fxml"));
        relatorio = new Scene(fxmlRelatorio);

        primaryStage.setResizable(false);
        //stage.initStyle(StageStyle.UNDECORATED);
        //stage.getIcons().add(new Image(getClass().getResourceAsStream("/icone.jpg")));
        primaryStage.setScene(inicio);
        primaryStage.show();
    }

    //Metodo que faz a navegação entre as telas
    public static void changeScreen(String scr, Object userData) {
        switch (scr) {
            case "inicio":
                stage.setScene(inicio);
                break;
            case "monitorar":
                stage.setScene(monitorar);
                notifyAllListeners("monitorar", scr);
                break;
            case "relatorio":
                stage.setScene(relatorio);
                notifyAllListeners("relatorio", scr);
                break;
        }
    }

    public static void changeScreen(String scr) {
        changeScreen(scr, null);
    }

    public static void main(String[] args) {
        launch(args);
    }

    public static ArrayList<OnChangeScreen> listeners = new ArrayList<>();

    public static interface OnChangeScreen {

        void onChangeScreen(String newScreen, Object userData);
    }

    public static void addOnChangeScreenListener(OnChangeScreen newListener) {
        listeners.add(newListener);
    }

    public static void notifyAllListeners(String newScreen, Object userData) {
        for (OnChangeScreen l : listeners) {
            l.onChangeScreen(newScreen, userData);
        }
    }

}

Другие вопросы по теме