[英]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.