将TitledPane内容弹出到窗口

时间:2016-06-27 21:25:30

标签: javafx javafx-8 accordion

我正在尝试获得手风琴的UI行为,用户可以在其中弹出任何TitledPane窗口,然后将窗口弹回到手风琴内的TitledPane

但是,当弹出折叠的TitledPane时,Stage中的内容未正确对齐,如果没有展开窗格,则根本不显示。

附件是显示问题的最小示例 - 请注意,我保留两个占位符窗格以避免内容节点(在我的情况下为A VBox)多次出现在场景图中。我尝试在preferredSize上设置visibleVBox属性,并在显示之前和之后调用layout,甚至以编程方式扩展标题窗格,但似乎没有任何效果。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        TitledPane t1 = new TitledPane();
        TitledPane t2 = new TitledPane();
        Accordion accordion = new Accordion(t1, t2);
        t1.setContent(buildComponent("Pane 1", t1, accordion));
        t2.setContent(buildComponent("Pane 2", t2, accordion));

        primaryStage.setScene(new Scene(accordion, 300, 300));
        primaryStage.show();
    }

    private VBox buildComponent(String name, TitledPane titledPane, Accordion holder) {
        final Button popout = new Button("Pop out");
        titledPane.setGraphic(popout);
        titledPane.setText(name);
        final VBox component = new VBox(new Label(name), new TableView<>());
        final Pane placeholder1 = new Pane();
        final Pane placeholder2 = new Pane();
        Stage st = new Stage();
        st.setScene(new Scene(placeholder1, 300, 300));

        popout.setOnAction(event -> {
            if (!st.equals(component.getScene().getWindow())) {
                holder.getPanes().remove(titledPane);
                titledPane.setContent(placeholder2);
                st.getScene().setRoot(component);
                st.show();
            }
        });

        st.setOnHidden(windowEvent -> {
            st.getScene().setRoot(placeholder1);
            titledPane.setContent(component);
            holder.getPanes().add(titledPane);
        });

        return component;
    }

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

结果说明:
没有窗格展开时的结果:
Result when no pane is expanded
展开其他窗格时的结果。请注意标签不可见:
Result when other pane is expanded. Note how the label is not visible.
窗格展开时的结果 - 这是我希望在所有情况下都具有的结果:
Result when pane is expanded - this is the result I want to have in all cases.

1 个答案:

答案 0 :(得分:0)

经过多次游戏后,我找到了一种解决此问题的方法,使用AnchorPane而不是直接设置Stage的根和TitledPane的内容:

private VBox buildComponent(String name, TitledPane titledPane, Accordion holder) {
    final Button popout = new Button("Pop out");
    titledPane.setGraphic(popout);
    titledPane.setText(name);
    final VBox component = new VBox(new Label(name), new TableView<>());
    final AnchorPane placeholder1 = new AnchorPane();
    final AnchorPane placeholder2 = new AnchorPane();
    AnchorPane.setTopAnchor(component, 0D);
    AnchorPane.setBottomAnchor(component, 0D);
    AnchorPane.setLeftAnchor(component, 0D);
    AnchorPane.setRightAnchor(component, 0D);
    Stage st = new Stage();
    st.setScene(new Scene(placeholder1, 300, 300));
    titledPane.setContent(placeholder2);
    placeholder2.getChildren().add(component);

    popout.setOnAction(event -> {
        if (!st.equals(component.getScene().getWindow())) {
            holder.getPanes().remove(titledPane);
            placeholder2.getChildren().clear();
            placeholder1.getChildren().add(component);
            st.show();
        }
    });

    st.setOnHidden(windowEvent -> {
        placeholder1.getChildren().clear();
        placeholder2.getChildren().add(component);
        holder.getPanes().add(titledPane);
    });

    return component;
}

这个新buildComponent还会将VBox添加到TitledPane,因此应删除对问题中TitledPane#setContent的调用。

我仍然有兴趣知道为什么会出现这个问题,或者如果有办法解决它而没有将我的窗格包含在另一个窗格(我的情况下为AnchorPane)。