JavaFX ScrollPane的水平滚动条隐藏内容

我将一些内容包装到ScrollPane中,因为如果内容不适合屏幕显示,我需要水平滚动条.

只要不需要滚动条,一切都很好:
JavaFX ScrollPane的水平滚动条隐藏内容

但是,显示滚动条时,它(垂直)隐藏了部分内容:
JavaFX ScrollPane的水平滚动条隐藏内容

如何防止这种行为?内容应始终完整显示.我尝试使用fitToHeight =“ true”,但这没有帮助.

下面是一些FXML示例(添加了HBox和VBox的多层以模仿我的真实应用程序的结构):

<BorderPane>
    <top>
        <ScrollPane vbarPolicy="NEVER" fitToHeight="true">
            <HBox>
                <VBox>
                    <TitledPane text="Title">
                        <HBox spacing="100.0">
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                            <Text text="Test1 Test2 Test3 Test4"></Text>
                        </HBox>
                    </TitledPane>
                </VBox>
            </HBox>
        </ScrollPane>
    </top>
    <center>

    </center>
    <bottom>

    </bottom>
</BorderPane>

解决方法:

看起来像是ScrollPaneSkin中的错误(reported):如果策略为AS_NEEDED并且scrollBar是可见的,则它的computePrefHeight方法不考虑scrollBar的高度.

因此,解决方法是执行此操作的自定义皮肤;)请注意,如果将策略从ALWAYS更改为AS_NEEDED(在调用computeXX时,该条是可见的-不太清楚为什么),这样做还不够.我们正在听政策上的变化,并且躲避酒吧..粗鲁但有效.

定制皮肤(请注意:不是正式的睾丸!)和驱动程序可用于:

public class ScrollPaneSizing extends Application{

    public static class DebugScrollPaneSkin extends ScrollPaneSkin {

        public DebugScrollPaneSkin(ScrollPane scroll) {
            super(scroll);
            registerChangeListener(scroll.hbarPolicyProperty(), p -> {
                // rude .. but visibility is updated in layout anyway
                getHorizontalScrollBar().setVisible(false);
            });
        }

        @Override
        protected double computePrefHeight(double x, double topInset,
                double rightInset, double bottomInset, double leftInset) {
            double computed = super.computePrefHeight(x, topInset, rightInset, bottomInset, leftInset);
            if (getSkinnable().getHbarPolicy() == ScrollBarPolicy.AS_NEEDED && getHorizontalScrollBar().isVisible()) {
                // this is fine when horizontal bar is shown/hidden due to resizing
                // not quite okay while toggling the policy
                // the actual visibilty is updated in layoutChildren?
                computed += getHorizontalScrollBar().prefHeight(-1);
            }
            return computed;
        }


    }

    private Parent createContent() {
        HBox inner = new HBox(new Text("somehing horizontal and again again ........")); 
        TitledPane titled = new TitledPane("my title", inner);
        ScrollPane scroll = new ScrollPane(titled) {

            @Override
            protected Skin<?> createDefaultSkin() {
                return new DebugScrollPaneSkin(this);
            }

        };
        scroll.setVbarPolicy(NEVER);
        scroll.setHbarPolicy(ALWAYS);
        // scroll.setFitToHeight(true);

        Button policy = new Button("toggle HBarPolicy");
        policy.setOnAction(e -> {
            ScrollBarPolicy p = scroll.getHbarPolicy();
            scroll.setHbarPolicy(p == ALWAYS ? AS_NEEDED : ALWAYS);
        });
        HBox buttons = new HBox(10, policy);
        BorderPane content = new BorderPane();
        content.setTop(scroll);
        content.setBottom(buttons);
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent(), 400, 200));
        stage.setTitle(FXUtils.version());
        stage.show();
    }

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

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(ScrollPaneSizing.class.getName());

}
上一篇:JavaFX标签换行文本行间距


下一篇:Javafx SSL客户端配置消耗我的Spring Boot SSL安全的Rest Api