簡體   English   中英

JavaFX setHgrow / 綁定屬性無限擴展

[英]JavaFX setHgrow / binding property expanding infinitely

這是我的代碼:

public class TestPanel extends ScrollPane {

    final int SPACING = 5;
    final int ROW_MAX = 6;

    public TestPanel(ArrayList<Item> items) {

        VBox root = new VBox(); 
        root.setSpacing(SPACING);
        HBox row = null;

        int count = 0;
        for (Item item: items){
            if (count == ROW_MAX || row == null){
                row = new HBox();
                row.setSpacing(SPACING);

                root.getChildren().add(row);
                count = 0;
            }

            CustomBox box = new customBox(item);
            row.getChildren().add(box);

            HBox.setHgrow(box, Priority.ALWAYS);

            //box.prefWidthProperty().bind(row.widthProperty());      // Worked for GridPane

            count++;
        }

        setFitToWidth(true);
        setContent(root);

    }

這是我放置在 V 和 H 框中的自定義框節點元素

public class CustomBox extends StackPane {

    private Items item;
    private Rectangle square;

    private int size = 20; // Irrelevent

    public CustomBox(NewAirbnbListing item) {
        this.item= item;

        setPadding(new Insets(5, 5, 5, 5));

        square = new Rectangle(size, size, Color.RED);


        square.widthProperty().bind(widthProperty());
        //square.heightProperty().bind(heightProperty());


        minHeightProperty().bind(widthProperty()); // Maintains aspect ratio

        getChildren().add(square);

    }

錯誤:粉紅色是方框,灰色是用於視覺測試的 StackPane 的背景顏色。

在此處輸入圖像描述

我想做的事:

在此處輸入圖像描述

我想要什么:我希望 CustomBox 內的矩形(以及我稍后將添加的其他組件)填充它們所在的 StackPane 的大小,並在調整 window 大小時改變它們的大小。 我基本上希望他們模仿那個窗格的大小。

現在嘗試解釋發生了什么,基本上我有一個 class,它基本上是一個正方形(稍后會有更多的東西),我想用它填充我的“網格”。 當我第一次這樣做時,我使用 GridPane 來擴展我的 class,我還使用注釋掉的代碼來綁定屬性並且它“完美地”工作,它調整了我想要的大小沒有任何問題,除了它像瘋了一樣滯后的事實因為items ArrayList 包含數千個項目,因此這將是一個很長的列表。 后來,當我實現存儲圖像的盒子時,大量的滯后問題就開始了。 我的解決方案是用 HBox 和 VBox 組合替換 GridPane,它很好地解決了延遲問題,它還讓我可以做一些我不能用 GridPane 做的事情。 但是,我鏈接的 gif 中的問題是我面臨的問題。 我已經嘗試了我能想到的所有綁定屬性組合,但它仍然像瘋了一樣擴展,我只是不知道是什么原因造成的,所以我真的希望這里有人能幫助我。 我不知道 JavaFX,但我是來學習的,非常感謝任何幫助。

我相信您的問題的根本原因在於: square寬度與CustomBox寬度綁定。 你可能想知道這是怎么回事。 您允許 CustomBox 寬度依賴於它的內容(又名正方形),而您的正方形寬度依賴於它的父寬度。因為現在這兩個寬度是相互依賴的。寬度呈指數增長。

解決此問題的一種可能方法是根據 ScrollPane 視口寬度手動計算 CustomBox 大小。 通過這種方式,您可以手動控制父寬度,而內容寬度由綁定處理。

TestPanel 中的代碼將是:

private DoubleProperty size = new SimpleDoubleProperty();

double padding = 4; // 2px on either side
viewportBoundsProperty().addListener((obs, old, bounds) -> {
    size.setValue((bounds.getWidth() - padding - ((ROW_MAX - 1) * SPACING)) / ROW_MAX);
});

CustomBox box = new CustomBox(item);
box.minWidthProperty().bind(size);

一個完整的工作演示如下:

在此處輸入圖像描述

import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class ScrollPaneContentDemo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        List<Item> items = new ArrayList<>();
        IntStream.range(1, 1000).forEach(i -> items.add(new Item()));
        TestPanel root = new TestPanel(items);
        Scene scene = new Scene(root, 500, 500);
        stage.setScene(scene);
        stage.setTitle("ScrollPaneContent Demo");
        stage.show();
    }

    class TestPanel extends ScrollPane {
        private final int SPACING = 5;
        private final int ROW_MAX = 6;
        private DoubleProperty size = new SimpleDoubleProperty();

        public TestPanel(List<Item> items) {
            final VBox root = new VBox();
            root.setSpacing(SPACING);
            HBox row = null;
            int count = 0;
            for (Item item : items) {
                if (count == ROW_MAX || row == null) {
                    row = new HBox();
                    row.setSpacing(SPACING);
                    root.getChildren().add(row);
                    count = 0;
                }

                CustomBox box = new CustomBox(item);
                box.minWidthProperty().bind(size);
                row.getChildren().add(box);
                HBox.setHgrow(box, Priority.ALWAYS);
                count++;
            }
            setFitToWidth(true);
            setContent(root);

            double padding = 4;
            viewportBoundsProperty().addListener((obs, old, bounds) -> {
                size.setValue((bounds.getWidth() - padding - ((ROW_MAX - 1) * SPACING)) / ROW_MAX);
            });
        }
    }

    class CustomBox extends StackPane {
        private Item item;
        private Rectangle square;
        private int size = 20;

        public CustomBox(Item item) {
            setStyle("-fx-background-color:#99999950;");
            this.item = item;
            setPadding(new Insets(5, 5, 5, 5));
            square = new Rectangle(size, size, Color.RED);
            square.widthProperty().bind(widthProperty());
            square.heightProperty().bind(heightProperty());

            maxHeightProperty().bind(minWidthProperty());
            maxWidthProperty().bind(minWidthProperty());
            minHeightProperty().bind(minWidthProperty());
            getChildren().add(square);
        }
    }

    class Item {
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM