JavaFX 有没有办法充分利用 TilePane 或 FlowPaneand网格窗格?
这是我想要实现的目标:
首先,我喜欢 GridPane 的想法,我可以在其中设置一个 M×N 网格,该网格会在其父容器内自动调整大小,以将空间平均划分为 M 列和 N 行。然后我可以放置一些完全填充每个单元格的子元素,它们将沿着网格拉伸。这很酷。
但有一个缺点:我需要通过设置其行号和列号来明确指定每个控件的位置。
然后,还有诸如 FlowPane 或 TilePane 之类的布局容器,当父容器更改其大小时,它们会自动重排其子元素。当我添加另一个子元素时,它会自动附加到列表的末尾,并且当空间太少而无法容纳另一个元素时,元素列表在到达容器边缘后会自动换行。
但这也有一个缺点:子元素只能具有严格的预定义大小。它们不会随其父元素一起拉伸。
这就是我需要的:
我需要这两个容器的最佳性能,也就是说,我想要一个 M × N 网格(比方说 4×4),其中每个单元格的父宽度/M × 父高度/N 并沿着窗口延伸,以便它始终4×4 个单元格,但它们的大小(及其内容的大小)会相应地拉伸。
但我不想明确告诉容器将我添加的每个新子项放在哪一行和哪一列中。相反,我只想添加它,并让容器找出要放入的第一个空单元格,从左到右填充单元格,如果当前行中没有空单元格,则从上到下填充单元格。
这些预定义容器的属性是否有一些神奇的设置可以让我实现这一目标?还是我需要自己写一个这样的容器?
正是出于您所描述的目的,我创建了ButtonGridPane
。这是初稿,还有改进的空间,但也许它可以给你一个基本的想法。
public class ButtonGrid extends Pane {
private static final double DEFAULT_RATIO = 0.618033987;
private int columnCount;
private double ratio;
public ButtonGrid(int columnCount) {
this(columnCount, DEFAULT_RATIO);
}
public ButtonGrid(int columnCount, double heightToWidthRatio) {
getStyleClass().add("button-grid");
this.columnCount = columnCount;
ratio = heightToWidthRatio;
}
public void setColumnCount(int columnCount) {
this.columnCount = columnCount;
}
public void setHeightToWidthRatio(double ratio) {
this.ratio = ratio;
}
@Override
public Orientation getContentBias() {
return Orientation.HORIZONTAL;
}
@Override
protected void layoutChildren() {
double left = getInsets().getLeft();
double top = getInsets().getTop();
double tileWidth = calculateTileWidth(getWidth());
double tileHeight = calculateTileHeight(getWidth());
ObservableList<Node> children = getChildren();
double currentX = left;
double currentY = top;
for (int idx = 0; idx < children.size(); idx++) {
if (idx > 0 && idx % columnCount == 0) {
currentX = left;
currentY = currentY + tileHeight;
}
children.get(idx).resize(tileWidth, tileHeight);
children.get(idx).relocate(currentX, currentY);
currentX = currentX + tileWidth;
}
}
@Override
protected double computePrefWidth(double height) {
double w = 0;
for (int idx = 0; idx < columnCount; idx++) {
Node node = getChildren().get(idx);
w += node.prefWidth(-1);
}
return getInsets().getLeft() + w + getInsets().getRight();
}
@Override
protected double computePrefHeight(double width) {
double h = calculateTileHeight(width) * getRowCount();
return getInsets().getTop() + h + getInsets().getBottom();
}
private double calculateTileHeight(double width) {
return calculateTileWidth(width) * ratio;
}
private double calculateTileWidth(double width) {
return (-getInsets().getLeft() + width - getInsets().getRight()) / columnCount;
}
private int getRowCount() {
return getChildren().size() / columnCount;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)