【问题标题】:JavaFX - Overlapping panesJavaFX - 重叠窗格
【发布时间】:2020-02-02 18:14:17
【问题描述】:

我正在尝试找到一个解决方案,其中一个层可以与另一个层重叠,而不会将其推向任何方向。类似这样:https://docs.oracle.com/javase/7/docs/api/javax/swing/JLayeredPane.html 但在 JavaFX 中。

这似乎是一个非常基本的功能,但我真的找不到解决方案。

我想要达到的效果如下:

我想要一个根Node,假设是一个BorderPane,它的left 有一个(设置)pane,它的center 是主要内容。当用户单击center 中的按钮时,left 窗格将显示,而无需将center 窗格推到右侧。这就是问题所在,因为期望的行为是在居中的内容上方而不是在它旁边。

toFronttoBack 函数乍一看似乎是一个可行的解决方案,但它只会改变渲染顺序。

不幸的是,我认为BorderPane 无法解决此问题,因为它无法管理重叠。但让我们希望我在这里错了。使用BorderPane 来实现这一点不是强制性的。如果它的工作方式与我在上一节中提到的相似,就足够了。

也许可以通过SubScene 来实现,但我真的不知道怎么做。

SubScene 文档: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/SubScene.html


非常感谢任何帮助。

更新:示例图片

【问题讨论】:

  • 不确定这是否会对您有所帮助,但您是否看过这个 Stack Overflow 问题:How to solve the overlapping of the controls each other belonging to two different panes
  • 如果右侧内容窗格在“打开”时不会将主内容窗格推向左侧,这将是一个可能的解决方案。我想实现重叠。问题是每当调整其中一个窗格的大小时,它也会推动另一个窗格。
  • 你不能使用 StackPane 并将重叠节点的对齐设置为 CENTER_RIGHT 并使用 toForth() 吗?或者可能是 CENTER 的 BorderPane,其中有您的侧边栏。
  • BorderPane 可能不是为此使用的最佳布局。我已经发布了一个至少部分满足您需要的答案:stackoverflow.com/a/37236961/2991525 A StackPane 应用到背景窗格的边距等于菜单的未展开大小可以负责调整菜单大小并使事情变得比我 3 年前提出的解决方案要简单一些...

标签: javafx layer overlap pane


【解决方案1】:

与@Nand 和@LBald 的建议相同,我也认为在这种情况下 StackPane 可能是一个不错的选择。下面是一个快速演示,展示了带有一点淡入淡出效果的覆盖节点。

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.stream.Stream;

public class OverlayLayout_Demo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Node Overlay Demo");
        primaryStage.show();

        HBox hBox = new HBox(new Button("One"), new Button("Two"));
        hBox.setPadding(new Insets(10));
        hBox.setSpacing(10);
        StackPane hPane = new StackPane(hBox);
        hPane.setMaxHeight(100);
        hPane.setVisible(false);
        hPane.setStyle("-fx-background-color:#55555550");

        VBox vBox = new VBox(new Button("One"), new Button("Two"));
        vBox.setPadding(new Insets(10));
        vBox.setSpacing(10);
        StackPane vPane = new StackPane(vBox);
        vPane.setMaxWidth(100);
        vPane.setVisible(false);
        vPane.setStyle("-fx-background-color:#55555550");

        Button left = new Button("Left");
        Button top = new Button("Top");
        Button right = new Button("Right");
        Button bottom = new Button("Bottom");
        VBox buttons = new VBox(left, top, right, bottom);
        buttons.setStyle("-fx-border-width:2px;-fx-border-color:black;");
        buttons.setSpacing(10);
        buttons.setAlignment(Pos.CENTER);
        StackPane.setMargin(buttons, new Insets(15));

        StackPane content = new StackPane(buttons);
        content.setOnMouseClicked(e -> {
            Node node = vPane.isVisible() ? vPane : hPane;
            FadeTransition ft = new FadeTransition(Duration.millis(300), node);
            ft.setOnFinished(e1 -> node.setVisible(false));
            ft.setFromValue(1.0);
            ft.setToValue(0.0);
            ft.play();
        });

        root.getChildren().addAll(content, hPane, vPane);

        Stream.of(left, top, right, bottom).forEach(button -> {
            button.setOnAction(e -> {
                vPane.setVisible(false);
                hPane.setVisible(false);
                Node node;
                switch (button.getText()) {
                    case "Left":
                    case "Right":
                        node = vPane;
                        StackPane.setAlignment(vPane, button.getText().equals("Left") ? Pos.CENTER_LEFT : Pos.CENTER_RIGHT);
                        break;
                    default:
                        node = hPane;
                        StackPane.setAlignment(hPane, button.getText().equals("Top") ? Pos.TOP_CENTER : Pos.BOTTOM_CENTER);
                }
                node.setVisible(true);
                FadeTransition ft = new FadeTransition(Duration.millis(300), node);
                ft.setFromValue(0.0);
                ft.setToValue(1.0);
                ft.play();
            });
        });
    }

    public static void main(String... args) {
        Application.launch(args);
    }
}

【讨论】:

    【解决方案2】:

    您可以使用简单的Pane 来处理主要内容和配置重叠窗格,然后在主要内容中添加一个侦听器以更改配置窗格的可见性。

    Pane container = new Pane();
    Pane mainContent = ... ; 
    // you main content pane stuff
    Pane config = ... ;
    // your config pane stuff
    container.getChildren().addAll(mainContent, config); // in this order
    mainContent.setOnMouseClicked(e -> config.setVisible( ! config.isVisible()) );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多