javafx - 如何解决属于两个不同 Pane 的控件相互重叠的问题

标签 javafx javafx-2

尝试制作一个隐藏/显示右侧窗口/ Pane 的切换按钮。这是一个演示示例:

package demoapp;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class DemoApp extends Application {

    private static final String styleHide = "-fx-skin: \"com.sun.javafx.scene.control.skin.ButtonSkin\"; -fx-base: gray; -fx-padding: 2; -fx-font-weight: bold; -fx-text-fill: #FFF; -fx-background-radius: 0 10 10 0;";
    private static final String styleShow = "-fx-skin: \"com.sun.javafx.scene.control.skin.ButtonSkin\"; -fx-base: gray; -fx-padding: 2; -fx-font-weight: bold; -fx-text-fill: #FFF; -fx-background-radius: 10 0 0 10;";
    private final double minWidth = 5;
    private final double maxWidth = 170;
    private boolean hidden = true;

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

    @Override
    public void start(Stage primaryStage) {
        BorderPane borderPane = new BorderPane();
        borderPane.setRight(getRightContent());

        VBox box = new VBox();
        box.setStyle("-fx-background-color: lightgray");
        box.setAlignment(Pos.CENTER_RIGHT);
        box.getChildren().add(new Label("Main Content"));
        box.getChildren().add(new Button("Button1"));
        borderPane.setCenter(box);

        StackPane root = new StackPane();
        root.getChildren().add(borderPane);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    private GridPane getRightContent() {

        final Button btn = new Button(" toggle button ");
        final GridPane pane = new GridPane();

        btn.setPrefHeight(40);
        btn.setFocusTraversable(false);
        btn.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                toggleRightContent(btn, pane);
            }
        });

        toggleRightContent(btn, pane);

        Text txt = new Text("Right Content");
        txt.setWrappingWidth(maxWidth - 20);

        pane.setVgap(10);
        pane.setStyle("-fx-padding: 5; -fx-background-color: gray");
        pane.addColumn(0, btn, txt);

        return pane;
    }

    private void toggleRightContent(Button btn, Pane pane) {
        if (hidden) {
            btn.setTranslateX(-5);
            btn.setStyle(styleHide);
            pane.toBack();
            pane.setMaxWidth(maxWidth);
            pane.setMinWidth(maxWidth);
            pane.setPrefWidth(maxWidth);
        } else {
            btn.setTranslateX(-113);
            btn.setStyle(styleShow);
            pane.toFront();
            pane.setMaxWidth(minWidth);
            pane.setMinWidth(minWidth);
            pane.setPrefWidth(minWidth);
        }
        hidden = !hidden;
    }
}

问题是,这个切换按钮与主要内容中的 Button1 部分重叠,并阻止其点击。这是因为上面的 pane.toFront(); 代码。如果我删除此行,那么这次 Button1 会阻止切换按钮在其上单击。
我怎么解决这个问题?或者是否有其他方法以不同的方式实现切换按钮功能?
谢谢。

最佳答案

您使用什么版本的 JavaFX?

使用 Java 2.1(开发人员预览版),您的应用程序看起来如下:enter image description here

更新:

您已将 Button 放在右侧 Pane 中,因此将其放在前面会阻止底部 Pane 获取事件。

最好将 Button 置于根目录,这样它就不会依赖于内容 Pane :

public class AccordionStyleButton extends Application {

    private static final String styleHide = "-fx-skin: \"com.sun.javafx.scene.control.skin.ButtonSkin\"; -fx-base: gray; -fx-padding: 2; -fx-font-weight: bold; -fx-text-fill: #FFF; -fx-background-radius: 0 10 10 0;";
    private static final String styleShow = "-fx-skin: \"com.sun.javafx.scene.control.skin.ButtonSkin\"; -fx-base: gray; -fx-padding: 2; -fx-font-weight: bold; -fx-text-fill: #FFF; -fx-background-radius: 10 0 0 10;";
    private final double minWidth = 5;
    private final double maxWidth = 170;
    private boolean hidden = true;

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

    private Pane root;

    @Override
    public void start(Stage primaryStage) {
        BorderPane borderPane = new BorderPane();
        root = new Pane();
        root.getChildren().add(borderPane);

        borderPane.prefWidthProperty().bind(root.widthProperty());
        borderPane.prefHeightProperty().bind(root.heightProperty());

        final Pane rightPane = getRightContent();
        borderPane.setRight(rightPane);

        VBox box = new VBox();
        box.setStyle("-fx-background-color: lightgray;");
        box.setAlignment(Pos.CENTER_RIGHT);
        box.getChildren().add(new Label("Main Content"));
        box.getChildren().add(new Button("Button1"));
        box.getChildren().add(new Button("Button2"));
        borderPane.setCenter(box);

        primaryStage.setScene(new Scene(root, 300, 250));

        final Button btn = new Button(" toggle button ");
        btn.setPrefHeight(40);
        btn.setFocusTraversable(false);
        btn.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                toggleRightContent(btn, rightPane);
            }
        });

        root.getChildren().add(btn);
        toggleRightContent(btn, rightPane);

        primaryStage.show();
    }


    private GridPane getRightContent() {
        GridPane pane = new GridPane();

        Text txt = new Text("Right Content");
        txt.setWrappingWidth(maxWidth - 20);

        pane.setVgap(10);
        pane.setStyle("-fx-padding: 5; -fx-background-color: gray;");
        pane.addColumn(0, txt);

        return pane;
    }

    private void toggleRightContent(Button btn, Pane pane) {
        if (hidden) {
            btn.setStyle(styleHide);
            pane.setMaxWidth(maxWidth);
            pane.setMinWidth(maxWidth);
            pane.setPrefWidth(maxWidth);
            btn.layoutXProperty().bind(root.widthProperty().subtract(maxWidth));
        } else {
            btn.setStyle(styleShow);
            pane.setMaxWidth(minWidth);
            pane.setMinWidth(minWidth);
            pane.setPrefWidth(minWidth);
            btn.layoutXProperty().bind(root.widthProperty().subtract(minWidth).subtract(btn.widthProperty()));
        }
        hidden = !hidden;
    }
}

关于javafx - 如何解决属于两个不同 Pane 的控件相互重叠的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9837529/

相关文章:

java - 处理表格 View 中的按钮单击事件

java - 根据变量值选择方法

java - 媒体 : Play WAV file inside JAR

屏幕外的 JavaFx 视频尺寸

java - 使用 Ant 和 e(fx)clipse

JavaFX Canvas 无法在 StackPane 内正确调整大小

java - 如何将多个文本字段添加到数组列表 JavaFX

css - JavaFX ListView - CellFactory 样式

JavaFX - 边框半径<->背景颜色

canvas - 在 JavaFX 中使用 MouseEvent 和 MouseClicked 选择并移动 Canvas 图像