使用JavaFX显示不同视图/布局/内容的有效方法

时间:2017-08-25 09:02:13

标签: java javafx layout

我有一个菜单,应该用于浏览不同的“视图”(布局)。菜单应始终可见。唯一应该改变的是显示的内容,取决于所选的菜单项。

我有一个非常基本的例子,使用下面创建的两个类:

public class Main extends Application{

    static final Pane pane = new Pane();

    public void start(Stage stage) {
        pane.getChildren().addAll(Menu.getPaneMenu());
        Scene scene = new Scene(pane);
        stage.setScene(scene);
        stage.setMaximized(true);
        stage.show();
    }

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

public class Menu {
    private static final Pane paneMenu = new Pane();

    static Pane getPaneMenu() {
        Button btn1 = new Button("Menu 1");
        btn1.relocate(100, 10);
        btn1.setPrefSize(100, 20);
        btn1.setOnAction(e -> {
            Label lbl = new Label("You clicked Menu1");
            lbl.relocate(200, 40);
            Main.pane.getChildren().add(lbl);
        });


        Button btn2 = new Button("Menu 2");
        btn2.relocate(300, 10);
        btn2.setPrefSize(100, 20);
        btn2.setOnAction(e -> {
            Label lbl = new Label("You clicked Menu2");
            lbl.relocate(200, 40);
            Main.pane.getChildren().add(lbl);
        });
        paneMenu.getChildren().addAll(btn1, btn2);

        return paneMenu;
    }
}

我面临的挑战是,单击菜单时,旧菜单会保留(如您所见,显示的文本会覆盖另一个): enter image description here

解决这种重叠的有效方法是什么?

2 个答案:

答案 0 :(得分:0)

如何将标签声明为Menu类的字段(与按钮相同)?然后,您可以在pane中添加/删除它们。我稍微修改了你的代码 - 它应该适用于这种特殊情况:

class Menu {
  private static final Pane paneMenu = new Pane();
  private static final Button btn1 = new Button("Menu 1");
  private static final Button btn2 = new Button("Menu 2");
  private static final Label firstLabel = new Label("You clicked Menu1");
  private static final Label secondLabel = new Label("You clicked Menu2");

  static Pane getPaneMenu() {
    ObservableList<Node> mainPaneChildren = Main.pane.getChildren();

    btn1.relocate(100, 10);
    btn1.setPrefSize(100, 20);
    btn1.setOnAction(e -> {
      firstLabel.relocate(200, 40);
      if (mainPaneChildren.contains(secondLabel)) {
        mainPaneChildren.remove(secondLabel);
      }
      if (!mainPaneChildren.contains(firstLabel)) {
        mainPaneChildren.add(firstLabel);
      }
    });


    btn2.relocate(300, 10);
    btn2.setPrefSize(100, 20);
    btn2.setOnAction(e -> {
      secondLabel.relocate(200, 40);
      if (mainPaneChildren.contains(firstLabel)) {
        mainPaneChildren.remove(firstLabel);
      }
      if (!mainPaneChildren.contains(secondLabel)) {
        mainPaneChildren.add(secondLabel);
      }
    });
    paneMenu.getChildren().addAll(btn1, btn2);

    return paneMenu;
  }
}

如果有更多的元素而不仅仅是Label,那么将它们放在某种Pane中会更好。您可以添加/删除Pane。 顺便说一下 - 看看Working With Layouts in JavaFX?我不认为使用relocate()是一种很好的做法。

答案 1 :(得分:0)

以下是一个示例,说明如何在Pane中加载两个不同的BorderPane

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Sample extends Application {

    @Override public void start(Stage stage) {

        BorderPane root = new BorderPane();        

        Button loadSceneOne = new Button("Load Scene One");
        //Event hanlder to load scene one
        loadSceneOne.setOnAction((event)->{
            root.setCenter(getSceneOne());
        });

        //Event hanlder to load scene two
        Button loadSceneTwo = new Button("Load Scene Two");
        loadSceneTwo.setOnAction((event)->{
            root.setCenter(getSceneTwo());
        });

        VBox menu = new VBox();
        menu.getChildren().addAll(loadSceneOne, loadSceneTwo);

        root.setLeft(menu);       

        Scene scene = new Scene(root);   
        stage.setMaximized(true);
        stage.setScene(scene);
        stage.show();
    }

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

    //Scene One
    Pane getSceneOne()
    {
        Pane pane = new Pane();

        Label label = new Label("Scene One!");
        StackPane stackPane = new StackPane();
        stackPane.getChildren().add(label);

        pane.getChildren().add(stackPane);

        return pane;
    }

    //Scene Two
    Pane getSceneTwo()
    {
        Pane pane = new Pane();

        Label label = new Label("Scene Two!");
        StackPane stackPane = new StackPane();
        stackPane.getChildren().add(label);

        pane.getChildren().add(stackPane);

        return pane;
    }

}