【问题标题】:javafx - Navigation Sidebar with Togglejavafx - 带切换的导航侧边栏
【发布时间】:2018-07-15 18:44:10
【问题描述】:

因此,在 Windows 10 中,您会看到左侧带有图标的 Windows 菜单:

单击汉堡图标时,菜单会展开并显示文本。

扩展部分覆盖了内容。文字正在显示。并且在(滑动过渡)中进行了动画处理。

在我的应用程序中,我想在右侧制作一个类似的菜单(见蓝色部分):

我完全不知道如何获得这种效果。目前我制作了一个带有图形的按钮。我只显示图形,当我单击汉堡包时,我通过将 setContentDisplay(ContentDisplay.GRAPHIC_ONLY) 更改为 setContentDisplay(ContentDisplay.RIGHT) 来显示所有文本,这两种方法有问题。

  1. 它推送内容。
  2. 您无法添加过渡。

任何帮助将不胜感激,尤其是示例。


演示

我做了一个演示,展示了我目前拥有的东西:

public class Main extends Application {

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

  @Override
  public void start(Stage primaryStage) {

    BorderPane root = new BorderPane();

    JFXButton[] jfxButtons = {
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
    };

    JFXHamburger hamburger = new JFXHamburger();
    HamburgerNextArrowBasicTransition transition = new HamburgerNextArrowBasicTransition(hamburger);
    transition.setRate(-1);

    hamburger.setAlignment(Pos.CENTER_RIGHT);
    hamburger.setPadding(new Insets(5));
    hamburger.setStyle("-fx-background-color: #fff;");

    hamburger.setOnMouseClicked(event -> {
      transition.setRate(transition.getRate() * -1);
      transition.play();
      if (transition.getRate() == -1) {
        for (JFXButton jfxButton : jfxButtons) {
          jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        }
      } else {
        for (JFXButton jfxButton : jfxButtons) {
          jfxButton.setContentDisplay(ContentDisplay.RIGHT);
        }
      }
    });

    ScrollPane scrollPane = new ScrollPane();
    VBox vBox = new VBox();
    scrollPane.setContent(vBox);

    vBox.getStyleClass().add("content_scene_right");
    vBox.getChildren().add(hamburger);
    vBox.getChildren().addAll(jfxButtons);

    for (JFXButton jfxButton : jfxButtons) {
      jfxButton.setMaxWidth(Double.MAX_VALUE);
      jfxButton.setRipplerFill(Color.valueOf("#40E0D0"));
      VBox.setVgrow(jfxButton, Priority.ALWAYS);
      jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }
    vBox.setFillWidth(true);

    Label labelHoverOverTest = new Label("Testing label");

    VBox vbox2 = new VBox();
    vbox2.getChildren().addAll(labelHoverOverTest);
    vbox2.setAlignment(Pos.CENTER_RIGHT);

    root.setRight(scrollPane);
    root.setCenter(vbox2);

    Scene scene = new Scene(root);

    primaryStage.setMinWidth(400);
    primaryStage.setMinHeight(400);

    primaryStage.setScene(scene);
    primaryStage.show();

  }
}

我在这个演示中使用了 JFoenix 和 fontawesomefx,但它也可以是带有任何图形的 javafx 场景按钮。

以下是演示的一些图片:

如您所见,它将内容推送到中心,我无法添加任何过渡。

(这里是一个来自 bootstrap 的示例,让您了解我想让它看起来像什么 1:https://bootsnipp.com/snippets/Pa9xl,2:https://bootsnipp.com/snippets/featured/navigation-sidebar-with-toggle(这个内容仍然会移动,但它应该给你清楚我的愿景是什么))

【问题讨论】:

  • 对于每个项目,使用 LabelButton (JFXButton) 的组合。这样您就可以在更改包含菜单的面板的大小时为标签的显示设置动画。

标签: css javafx


【解决方案1】:

问题是您正在使用BorderPane 并将所有内容放在同一层上,因此当右侧的内容更改宽度时,它会影响中间的内容等。

为了避免这种情况,你应该让它分层,所以对于视图的root 使用StackPane,这个窗格应该有 2 个孩子,1 个用于主要内容,1 个用于侧边栏,确保侧边栏高于主要内容,现在这个 2 可以是任何你想要的Pane。这样侧边栏将被放置在主要内容之上,并且不会推送内容。

使用您提供的代码并添加 StackPane,您会得到如下结果:

@Override
public void start(Stage primaryStage) {

    StackPane root = new StackPane();
    BorderPane mainContent = new BorderPane();
    BorderPane sidebar = new BorderPane();

    JFXButton[] jfxButtons = {
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),
        new JFXButton("Some text", new FontAwesomeIconView(FontAwesomeIcon.LINK)),};

    JFXHamburger hamburger = new JFXHamburger();
    HamburgerNextArrowBasicTransition transition = new HamburgerNextArrowBasicTransition(hamburger);
    transition.setRate(-1);

    hamburger.setAlignment(Pos.CENTER_RIGHT);
    hamburger.setPadding(new Insets(5));
    hamburger.setStyle("-fx-background-color: #fff;");

    hamburger.setOnMouseClicked(event -> {
        transition.setRate(transition.getRate() * -1);
        transition.play();
        if (transition.getRate() == -1) {
            for (JFXButton jfxButton : jfxButtons) {
                jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            }
        } else {
            for (JFXButton jfxButton : jfxButtons) {
                jfxButton.setContentDisplay(ContentDisplay.RIGHT);
            }
        }
    });

    ScrollPane scrollPane = new ScrollPane();
    VBox vBox = new VBox();
    scrollPane.setContent(vBox);

    vBox.getStyleClass().add("content_scene_right");
    vBox.getChildren().add(hamburger);
    vBox.getChildren().addAll(jfxButtons);

    for (JFXButton jfxButton : jfxButtons) {
        jfxButton.setMaxWidth(Double.MAX_VALUE);
        jfxButton.setRipplerFill(Color.valueOf("#40E0D0"));
        VBox.setVgrow(jfxButton, Priority.ALWAYS);
        jfxButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }
    vBox.setFillWidth(true);

    Label labelHoverOverTest = new Label("Testing label");

    VBox vbox2 = new VBox();
    vbox2.getChildren().addAll(labelHoverOverTest);
    vbox2.setAlignment(Pos.CENTER_RIGHT);

    mainContent.setCenter(vbox2);
    sidebar.setRight(scrollPane);

    root.getChildren().addAll(mainContent, sidebar);

    Scene scene = new Scene(root);

    primaryStage.setMinWidth(400);
    primaryStage.setMinHeight(400);
    primaryStage.setScene(scene);
    primaryStage.show();
}

至于过渡,我不确定那里有什么问题,对我来说效果很好。

【讨论】:

  • 谢谢它的效果很好,我添加了@mrmcwolf 在他对您的帖子的评论中给出的解决方案。这正是我想要的。至于主要代码,我为效果更改了一些部分,例如将标签setVisible 设置为false 并将setMaxWidth 设置为0。这是为了删除菜单折叠的标签宽度。最后这里是我使用的帖子创建了自定义按钮:stackoverflow.com/a/18855502/7791653
猜你喜欢
  • 2019-07-07
  • 1970-01-01
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
相关资源
最近更新 更多