简体   繁体   中英

JavaFX FlowPane within ScrollPane, dynamically adjust scrollpane's content and size

I currently have a ScrollPane with a FlowPane as content. The FlowPane currently initializes with no children nodes, a fixed width and a pref/min height (but no max height).

While adding items to the FlowPane at runtime (I click some UI element and something is added to the FlowPane), the ScrollPane should adjust its height in the case that the addition to the FlowPane no longer fits.

I don't understand how to set the height of the flowPane and ScrollPane so that this works - if that's the problem to begin with. At the moment, whenever the addition to the FlowPane doesn't fit its initial height, the content is added, but not visible. The scrollbar belonging to the ScrollPane never adjusts its height - if it did, I could just scroll further down and see the content.

Let's say I have a ScrollPane with some width and height, some viewport width/height, and a FlowPane with some width/height - What should my settings be for the min/pref/max sizes? How can I make a scrollPane adjust its scrollbar behaviour or make the content visible?

The ScrollPane's setFitToHeight is already set to true, which didn't seem to change anything.

import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class FlowPaneTest extends Application
{

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

    @Override
    public void start(Stage primaryStage) throws Exception
    {

        // borderPane rootPane
        BorderPane borderPane = new BorderPane();
        borderPane.setMinSize(600, 600);
        borderPane.setPrefSize(600, 600);
        borderPane.setMaxSize(600, 600);
        // container for the two scrollPanes below
        FlowPane flow = new FlowPane();
        borderPane.setRight(flow);

        // two scrollPanes, each should resize it's height (width should be fixed) if
        // children are added beyond it's current height
        ScrollPane top = new ScrollPane();
        ScrollPane bottom = new ScrollPane();

        FlowPane scrollPaneContent = new FlowPane();
        top.setContent(scrollPaneContent);
        bottom.setContent(scrollPaneContent);

        flow.getChildren().add(top);
        flow.getChildren().add(bottom);

        borderPane.setOnMouseClicked(new EventHandler<Event>()
        {

            @Override
            public void handle(Event event)
            {

                Label l = new Label("test");
                l.setMinSize(100, 100);
                l.setPrefSize(100, 100);
                l.setMaxSize(100, 100);

                scrollPaneContent.getChildren().add(l);

            }
        });

        // size settings

        int width = 300, height = 300;

        top.setHvalue(0.5);

        top.setMinViewportHeight(height);
        top.setPrefViewportHeight(height);
        top.setMinViewportWidth(width);
        top.setPrefViewportWidth(width);
        top.setHbarPolicy(ScrollBarPolicy.ALWAYS);
        top.setFitToHeight(true);

        top.setMinSize(width, height);
        top.setPrefSize(width, height);
        top.setMaxWidth(width);

        scrollPaneContent.setMinSize(width, height);
        scrollPaneContent.setPrefSize(width, height);
        scrollPaneContent.setMaxWidth(width);
        scrollPaneContent.setPrefHeight(height);

        bottom.setMinSize(width, height);
        bottom.setPrefSize(width, height);
        bottom.setMaxWidth(width);
        bottom.setHvalue(0.5);

        bottom.setMinViewportHeight(height);
        bottom.setPrefViewportHeight(height);
        bottom.setMinViewportWidth(width);
        bottom.setPrefViewportWidth(width);
        bottom.setHbarPolicy(ScrollBarPolicy.ALWAYS);
        top.setFitToHeight(true);
        bottom.setFitToHeight(true);

        // stage
        Scene scene = new Scene(borderPane, 600.0, 600.0);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

尝试指定ScrollPane高度和宽度并添加此行

scrollPane.setFitToWidth(true);

Ending up with something similar to this ugly bit of code - It listens to the number of children in the pane and increases the size every time something is added to the list of children:

topSubPane.getChildren().addListener(new ListChangeListener()
    {

        @Override
        public void onChanged(Change c)
        {
            c.next();

            topSubPane.setPrefHeight(topSubPane.getHeight() + 50);

        }
    });

Works, but feels like an unorthodox hack. Is there really no regular way of doing this?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM