7

我在 JavaFX 8 中的 ScrollPane 根据需要显示滚动条时遇到了一些困难。我目前正在做的只是创建一个具有 x 个元素的 FlowPane,并将其设置为 ScrollPane 的内容。

当我垂直于 FlowPane 的方向收缩时,就会出现问题。当元素开始换行并越界时,滚动条不会出现。当我平行于方向收缩时,不会发生这种情况。我有一个小的 Java 程序来举例说明这个问题。

开始

平行收缩

收缩垂直

收缩垂直夸张 收缩平行夸张

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

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

       @Override
       public void start(Stage primaryStage) throws Exception {
             FlowPane flow = new FlowPane();
             flow.setStyle("-fx-border-color: red");
             addPanes(flow, 16);

             ScrollPane scroll = new ScrollPane(flow);
             scroll.setStyle("-fx-border-color: green");
             scroll.setFitToHeight(true);
             scroll.setFitToWidth(true);

             Scene scene = new Scene(scroll, 450, 450);
             primaryStage.setScene(scene);
             primaryStage.show();
       }

       public void addPanes(FlowPane root, int panes) {
             for(int i = 0; i < panes; i++) {
                    StackPane filler = new StackPane();
                    filler.setStyle("-fx-border-color: black");
                    filler.setPrefSize(100, 100);
                    root.getChildren().add(filler);
             }
       }
}
4

3 回答 3

2

您可以添加下面的代码以始终显示垂直滚动条。

scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
于 2017-11-03T13:50:12.023 回答
2

看看下面的代码,告诉我这是否是你想要实现的。我仍然不确定导致问题的原因,我将不得不查看 ScrollPane 的文档以找出答案。我的怀疑是setFitToWidth&setFitToHeight方法。虽然我仍然相信这不是一个错误。

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        FlowPane flow = new FlowPane();
        flow.setStyle("-fx-border-color: red");

        addPanes(flow, 16);

        ScrollPane scroll = new ScrollPane(flow);
        scroll.setStyle("-fx-border-color: green");

        // Apparently this cause the issue here.
        // scroll.setFitToHeight(true);
        // scroll.setFitToWidth(true);


        // Instead just make the flow pane take the dimensions of the ScrollPane
        // the -5 is to not show the Bars when both of panes have the same dimensions  
        flow.prefWidthProperty().bind(Bindings.add(-5, scroll.widthProperty()));
        flow.prefHeightProperty().bind(Bindings.add(-5, scroll.heightProperty()));

        Scene scene = new Scene(scroll, 450, 450);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public void addPanes(FlowPane root, int panes) {
        for (int i = 0; i < panes; i++) {
            HBox filler = new HBox();
            filler.setStyle("-fx-border-color: black");
            filler.setPrefSize(100, 100);
            root.getChildren().add(filler);
        }
    }
}

查看 ScrollPane 的文档,特别是setFitToHeight您会发现:

属性说明:如果为 true 并且包含的​​节点是 Resizable,则节点将保持调整大小以匹配 ScrollPane 视口的高度。如果包含的节点不是 Resizable,则忽略此值。

并且因为 ScrollPane 内的节点将保持调整大小以匹配 ScrollPane 视口的宽度和高度,这就是 Vertical ScrollBar 永远不会出现的原因。

于 2017-11-03T08:54:33.123 回答
0

当计算出 ScrollPane 内 FlowPane 所需的高度时,将传递 -1 的宽度值。当其所有内容都放入一行时,流窗格将报告所需的高度。

作为一种解决方法,您可以在这种情况下传递最后一次布局计算的宽度。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

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

       @Override
       public void start(Stage primaryStage) throws Exception {
             FlowPane flow = new FlowPane() {
                @Override protected double computeMinHeight(double width) {
                    double minHeight = super.computeMinHeight(width != -1 ? width : 
                        /* When no width is specified, use the current contol size*/ 
                        getWidth());
                    return minHeight;
                }
             };
             flow.setStyle("-fx-border-color: red");
             addPanes(flow, 16);

             ScrollPane scroll = new ScrollPane(flow);
             flow.maxWidthProperty().bind(scroll.widthProperty());
             scroll.widthProperty().addListener((observable, oldValue, newValue)->{
                 /* clearSizeCache */
                 flow.requestLayout();
             });

             scroll.setStyle("-fx-border-color: green");
             scroll.setFitToHeight(true);
             scroll.setFitToWidth(true);

             Scene scene = new Scene(scroll, 450, 450);
             primaryStage.setScene(scene);
             primaryStage.show();
       }

       public void addPanes(FlowPane root, int panes) {
             for(int i = 0; i < panes; i++) {
                    StackPane filler = new StackPane();
                    filler.setStyle("-fx-border-color: black");
                    filler.setPrefSize(100, 100);
                    root.getChildren().add(filler);
             }
       }
}
于 2019-08-13T12:15:09.490 回答