繁体   English   中英

JavaFX:多个“视图”、“页面”或场景 - 如何处理?

[英]JavaFX: Multiple 'views', 'pages' or scenes - how to approach?

我正在尝试使用 JavaFX 构建一个虚拟网上商店。我故意不使用 fxml、scenebuilder、maven 或任何其他构建工具。 只是普通的 JavaFX,为了真正了解基础知识。 但是,我在创建和浏览不同的“页面”时遇到了问题。

我尝试了各种创造性的解决方案,比如这个(是否允许发布链接?),但没有一个对我完全有效,因为我希望每个“页面”、“视图”或场景都在一个单独的 java class 文件中,以便保留所有内容结构有序。

我想我会为每个页面制作一个 Borderpane 作为父布局

abstract class WindowBase extends BorderPane {

    public abstract BorderPane render(App app);

    public WindowBase() {
    
        Label labelTop = new Label("Top box");

        HBox topBox = new HBox();
        topBox.setStyle("-fx-background-color: red;");
        topBox.getChildren().addAll(labelTop);

        Label labelLeft = new Label("Left box");

        VBox leftBox = new VBox();
        leftBox.setStyle("-fx-background-color: green;");
        leftBox.getChildren().addAll(labelLeft);

        Label labelRight = new Label("Right box");

        VBox rightBox = new VBox();
        rightBox.setStyle("-fx-background-color: blue;");
        rightBox.getChildren().addAll(labelRight);

        Label labelBottom = new Label("Bottom box");

        HBox bottomBox = new HBox();
        bottomBox.setStyle("-fx-background-color: yellow;");
        bottomBox.getChildren().addAll(labelBottom);

        this.setTop(topBox);
        this.setLeft(leftBox);
        this.setRight(rightBox);
        this.setBottom(bottomBox);
    }
}

和一个孩子,主页

public class Homepage extends WindowBase {

    public BorderPane render(App app) {

        Button button = new Button("Go to shopping cart");
        button.setOnAction((event) -> app.toShoppingCart());

        StackPane centerPane = new StackPane();
        centerPane.getChildren().add(button);
        this.setCenter(centerPane);

        return this;
    }
}

最后我的 App.java 运行一切

public class App extends Application{

    private WindowBase view;

    public void start(Stage stage) throws Exception {

        view = new Homepage();

        stage.setScene(new Scene(view.render(this)));
        stage.setFullScreen(true);
        stage.show();

    }

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

    public void toHomepage() {
        this.view = new Homepage();
    }

    public void toShoppingCart() {
        this.view = new ShoppingCart();
    }
}

我知道我不能将这个 (App) 作为参数传递给 view.render(),在方法 render 中使用参数并期望能够操作它,因为它只会创建一个新的 App 实例它到达那里。 但是,我也没有其他办法。

我尝试将导航按钮放置在 App class 中,以便能够操作视图,但是我无法从后续视图中调用按钮。

必须有一种方法可以实现我想要的,而无需在一个文件中编写完整的 GUI,对吗? 我应该改用我的观点 static 吗?

除了 BorderPanes,我当然也可以使用 Scenes,无论它是否有效。

我已经找到了我想要的解决方案。 把它贴在这里,供遇到同样情况的人使用。

Class WindowBase

public class WindowBase {

    public BorderPane getMainPane() {
    
        Label labelTop = new Label("Top box");
    
        HBox topBox = new HBox();
        topBox.setStyle("-fx-background-color: red;");
        topBox.getChildren().addAll(labelTop);

        Label labelLeft = new Label("Left box");

        VBox leftBox = new VBox();
        leftBox.setStyle("-fx-background-color: green;");
        leftBox.getChildren().addAll(labelLeft);

        Label labelRight = new Label("Right box");

        VBox rightBox = new VBox();
        rightBox.setStyle("-fx-background-color: blue;");
        rightBox.getChildren().addAll(labelRight);

        Label labelBottom = new Label("Bottom box");

        HBox bottomBox = new HBox();
        bottomBox.setStyle("-fx-background-color: yellow;");
        bottomBox.getChildren().addAll(labelBottom);

        BorderPane borderPane = new BorderPane();

        borderPane.setTop(topBox);
        borderPane.setLeft(leftBox);
        borderPane.setRight(rightBox);
        borderPane.setBottom(bottomBox);

        return borderPane;
    }
}

Class 主页

public class Homepage extends WindowBase {

    public BorderPane render(Button toShoppingCart) {

        Label label = new Label("This is the homepage.");
        label.setStyle(
                "-fx-font: normal bold 30px 'elephant'; -fx-text-fill: black; -fx-background-color: red;");

        StackPane stackPane = new StackPane();
        stackPane.getChildren().addAll(label);

        BorderPane mainPane = getMainPane();
        VBox leftBox = (VBox) mainPane.getLeft();
        leftBox.getChildren().add(toShoppingCart);

        //I do not understand why this works. I abstracted leftBox from mainPane, then added shoppingCart, but never added the abstracted
        //  leftBox back to the mainPane before returning it. This should not work, but it does. leftBox.getChildren().add(toShoppingCart)
        //  should have no effect.
        //However, mainPane.getChildren().add(leftBox) throws an IllegalArgumentException about duplicate components, which is to be
        //  expected if the leftBox is already automatically added back to the mainPane.

        mainPane.setCenter(stackPane);

        return mainPane;
    }
}

Class 购物车

public class ShoppingCart extends WindowBase {

    public ShoppingCart() {
        super();
    }

    public BorderPane render(Button toHomepage) {
        
        Label label = new Label("This is the shopping cart.");
        label.setStyle(
            "-fx-font: normal bold 30px 'elephant'; -fx-text-fill: black; -fx-background-color: red;");
        
        StackPane centerPane = new StackPane();
        centerPane.getChildren().add(label);
    
        BorderPane mainPane = getMainPane();
        VBox leftBox = (VBox) mainPane.getLeft();
        leftBox.getChildren().add(toHomepage);

        mainPane.setCenter(centerPane);

        return mainPane;
    }
}

Class 应用程序

public class App extends Application{

    Scene scene;

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

        Homepage homePane = new Homepage();
        Button toHomepage = new Button("Back to home page");

        ShoppingCart shoppingPane = new ShoppingCart();
        Button toShoppingCart = new Button("To shopping cart");

        toHomepage.setOnAction(e -> scene.setRoot(homePane.render(toShoppingCart)));
        toShoppingCart.setOnAction(e -> scene.setRoot(shoppingPane.render(toHomepage)));

        scene = new Scene(homePane.render(toShoppingCart), 600, 400);

        stage.setScene(scene);
        stage.setFullScreen(true);
        stage.show();

    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM