Javafx 如何解决属于两个不同窗格的控件之间的重叠问题

Javafx 如何解决属于两个不同窗格的控件之间的重叠问题,javafx,javafx-2,Javafx,Javafx 2,尝试创建隐藏/显示右侧窗口/窗格的切换按钮。下面是一个演示示例: 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; im

尝试创建隐藏/显示右侧窗口/窗格的切换按钮。下面是一个演示示例:

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;
    }
}
package-demoapp;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.layout.*;
导入javafx.scene.text.text;
导入javafx.stage.stage;
公共类DemoApp扩展应用程序{
私有静态最终字符串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背景半径:0 10 10;”;
私有静态最终字符串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背景半径:10;
专用最终双最小宽度=5;
专用最终双最大宽度=170;
私有布尔隐藏=真;
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
BorderPane BorderPane=新的BorderPane();
setRight(getRightContent());
VBox box=新的VBox();
框。设置样式(“-fx背景色:浅灰色”);
框。设置对齐(位置中心\右侧);
box.getChildren().add(新标签(“主要内容”);
box.getChildren().add(新按钮(“Button1”);
边框窗格。设置中心(框);
StackPane root=新的StackPane();
root.getChildren().add(边框窗格);
原始阶段。设置场景(新场景(根,300250));
primaryStage.show();
}
私有GridPane getRightContent(){
最终按钮btn=新按钮(“切换按钮”);
最终网格窗格=新网格窗格();
btn.setPrefHeight(40);
btn.setFocusTraversable(假);
btn.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent事件){
切换右内容(btn,窗格);
}
});
切换右内容(btn,窗格);
Text txt=新文本(“正确内容”);
setWrappingWidth(最大宽度-20);
窗格。设置间隙(10);
窗格.setStyle(“-fx填充:5;-fx背景色:灰色”);
pane.addColumn(0,btn,txt);
返回窗格;
}
private void toggleRightContent(按钮btn,窗格){
如果(隐藏){
btn.setTranslateX(-5);
btn.setStyle(样式隐藏);
pane.toBack();
窗格。设置最大宽度(最大宽度);
窗格。设置最小宽度(最大宽度);
窗格.setPrefWidth(maxWidth);
}否则{
btn.setTranslateX(-113);
btn.setStyle(styleShow);
pane.toFront();
窗格。设置最大宽度(最小宽度);
窗格。设置最小宽度(最小宽度);
窗格.setPrefWidth(最小宽度);
}
隐藏=!隐藏;
}
}
问题是,此切换按钮与主内容中的
按钮1
部分重叠,阻止其单击。这是因为
pane.toFront()上面的代码。如果我删除这一行,那么这次
按钮1
会阻止切换按钮在其上单击。
我怎样才能解决这个问题?或者是否有其他不同方式实现切换按钮功能?

谢谢。

您使用什么版本的JavaFX

有了Java 2.1(开发者预览版),您的应用程序看起来更像是下一代:

更新:

您已将按钮放在右侧窗格中,因此将其放在前面会阻止底部窗格获取事件

最好将按钮置于根目录,这样它就不会依赖于内容窗格:

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;
    }
}
公共类AccordionStyleButton扩展应用程序{
私有静态最终字符串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背景半径:0 10 10;”;
私有静态最终字符串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背景半径:10;
专用最终双最小宽度=5;
专用最终双最大宽度=170;
私有布尔隐藏=真;
公共静态void main(字符串[]args){
发射(args);
}
私有窗格根;
@凌驾
公共无效开始(阶段primaryStage){
BorderPane BorderPane=新的BorderPane();
root=新窗格();
root.getChildren().add(边框窗格);
borderPane.prefWidthProperty().bind(root.widthProperty());
borderPane.prefHeightProperty().bind(root.heightProperty());
最终窗格rightPane=getRightContent();
borderPane.setRight(右窗格);
VBox box=新的VBox();
box.setStyle(“-fx背景色:浅灰色;”);
框。设置对齐(位置中心\右侧);
box.getChildren().add(新标签(“主要内容”);
box.getChildren().add(新按钮(“Button1”);
box.getChildren().add(新按钮(“Button2”));
边框窗格。设置中心(框);
原始阶段。设置场景(新场景(根,300250));
最终按钮btn=新按钮(“切换按钮”);
btn.setPrefHeight(40);
btn.setFocusTraversable(假);
btn.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent事件){
切换右内容(btn,右窗格);
}
});
root.getChildren().add(btn);
切换右内容(btn,右窗格);
primaryStage.show();
}
私有GridPane getRightContent(){
GridPane=新建GridPane();
Text txt=新文本(“正确内容”);
setWrappingWidth(最大宽度-20);
窗格。设置间隙(10);
窗玻璃