javafx中的蜂窝布局(使用flowpane?)
我正试图在JavaFX中用按钮创建一个蜂窝状流,到目前为止,它是一个流窗格 到目前为止,我在FlowPane上使用了一个负的VGap,使它工作了一半,但一旦我调整它的大小,使3-4行变为3-3-1,它显然出了问题 我正试图找到一个解决方案,使蜂窝式布局中的按钮数量可变,但到目前为止,我还没有取得多少成功。所以我想知道是否有人知道这个问题的解决方案 编辑:这是我目前的基本代码javafx中的蜂窝布局(使用flowpane?),java,javafx,flowpane,Java,Javafx,Flowpane,我正试图在JavaFX中用按钮创建一个蜂窝状流,到目前为止,它是一个流窗格 到目前为止,我在FlowPane上使用了一个负的VGap,使它工作了一半,但一旦我调整它的大小,使3-4行变为3-3-1,它显然出了问题 我正试图找到一个解决方案,使蜂窝式布局中的按钮数量可变,但到目前为止,我还没有取得多少成功。所以我想知道是否有人知道这个问题的解决方案 编辑:这是我目前的基本代码 FlowPane root = new FlowPane(); root.setHgap(3.0); root.set
FlowPane root = new FlowPane();
root.setHgap(3.0); root.setVgap(-23.0);
root.setAlignment(Pos.CENTER);
Button[] array = new Button[7];
for(int i = 0; i <= 6; i++){
Button button = new Button();
button.setShape(polygon); (made a polygon in the same of a hexagon)
array[i] = button;
}
root.getChildren().addAll(array);
FlowPane root=newflowpane();
根.setHgap(3.0);根.setVgap(-23.0);
根部设置对齐(位置中心);
按钮[]数组=新按钮[7];
对于(int i=0;i)列/行
这比使用FlowPane
放置字段更方便
您可以观察到,使用列跨距,您可以将按钮放置在网格窗格中
:每个字段填充sqrt(3/4)的2列
乘以字段高度;奇数行/偶数行分别从第0/1列开始。每个字段填充3行,列约束的大小在字段高度的四分之一到一半之间交替
示例
public static GridPane createHoneyComb(int rows, int columns, double size) {
double[] points = new double[12];
for (int i = 0; i < 12; i += 2) {
double angle = Math.PI * (0.5 + i / 6d);
points[i] = Math.cos(angle);
points[i + 1] = Math.sin(angle);
}
Polygon polygon = new Polygon(points);
GridPane result = new GridPane();
RowConstraints rc1 = new RowConstraints(size / 4);
rc1.setFillHeight(true);
RowConstraints rc2 = new RowConstraints(size / 2);
rc2.setFillHeight(true);
double width = Math.sqrt(0.75) * size;
ColumnConstraints cc = new ColumnConstraints(width/2);
cc.setFillWidth(true);
for (int i = 0; i < columns; i++) {
result.getColumnConstraints().addAll(cc, cc);
}
for (int r = 0; r < rows; r++) {
result.getRowConstraints().addAll(rc1, rc2);
int offset = r % 2;
int count = columns - offset;
for (int c = 0; c < count; c++) {
Button b = new Button();
b.setPrefSize(width, size);
b.setShape(polygon);
result.add(b, 2 * c + offset, 2 * r, 2, 3);
}
}
result.getRowConstraints().add(rc1);
return result;
}
double[]点=新的double[12];
对于(int i=0;i<12;i+=2){
双角度=数学PI*(0.5+i/6d);
点[i]=数学cos(角度);
点[i+1]=数学sin(角度);
}
多边形=新多边形(点);
OffsetPane op=新的OffsetPane();
双字段高度=100;
双字段宽度=数学sqrt(0.75)*字段高度;
对于(int i=0;i<23;i++){
按钮按钮=新按钮();
按钮。设置形状(多边形);
按钮.setPrefSize(字段宽度、字段高度);
op.getChildren().add(按钮);
}
//水平放置正好位于最后一个元素的右侧
op.setHPositionFunction((int索引,双x,双y,双宽度,双高度)->新点2D(x+宽度,y));
//垂直位置为左/右尺寸的一半,具体取决于索引和
//1/4最后一个节点底部上方的节点高度
op.setVPositionFunction((整型索引,双x,双y,双宽度,双高度)->新点2D(x+(索引%2==0?宽度:-宽度)/2,y+高度*0.75));
我的水晶球在维护atm机上。如果没有代码,没有人能帮你…@Nidhoegger添加了我当前的代码,但我怀疑这会帮助muchAm纠正我的猜测,即这个蜂巢需要像FlowPane一样包装它的一行单元格来响应用户调整大小的动作?或者用户不允许调整它的大小?我弄得很糟糕我现在正在工作,但现在正在工作。OffsetPane正是我想要的,谢谢!
public class OffsetPane extends Pane {
public interface PositionFunction {
public Point2D getNextPosition(int index, double x, double y, double width, double height);
}
private static final PositionFunction DEFAULT_FUNCTION = new PositionFunction() {
@Override
public Point2D getNextPosition(int index, double x, double y, double width, double height) {
return new Point2D(x, y);
}
};
private final ObjectProperty<PositionFunction> hPositionFunction;
private final ObjectProperty<PositionFunction> vPositionFunction;
private ObjectProperty<PositionFunction> createPosProperty(String name) {
return new SimpleObjectProperty<PositionFunction>(this, name, DEFAULT_FUNCTION) {
@Override
public void set(PositionFunction newValue) {
if (newValue == null) {
throw new IllegalArgumentException();
} else if (get() != newValue) {
super.set(newValue);
requestLayout();
}
}
};
}
public OffsetPane() {
this.hPositionFunction = createPosProperty("hPositionFunction");
this.vPositionFunction = createPosProperty("vPositionFunction");
}
@Override
protected void layoutChildren() {
super.layoutChildren();
double width = getWidth();
List<Node> children = getManagedChildren();
final int childSize = children.size();
if (childSize > 0) {
int row = 0;
Node lastRowStart = children.get(0);
Node lastNode = lastRowStart;
lastRowStart.relocate(0, 0);
PositionFunction hFunc = getHPositionFunction();
PositionFunction vFunc = getVPositionFunction();
int index = 1;
int columnIndex = 0;
while (index < childSize) {
Node child = children.get(index);
Bounds lastBounds = lastNode.getLayoutBounds();
Bounds bounds = child.getLayoutBounds();
Point2D pt = hFunc.getNextPosition(columnIndex, lastNode.getLayoutX(), lastNode.getLayoutY(), lastBounds.getWidth(), lastBounds.getHeight());
if (pt.getX() + bounds.getWidth() > width) {
// break row
lastBounds = lastRowStart.getLayoutBounds();
pt = vFunc.getNextPosition(row, lastRowStart.getLayoutX(), lastRowStart.getLayoutY(), lastBounds.getWidth(), lastBounds.getHeight());
child.relocate(pt.getX(), pt.getY());
lastRowStart = child;
row++;
columnIndex = 0;
} else {
child.relocate(pt.getX(), pt.getY());
columnIndex++;
}
lastNode = child;
index++;
}
}
}
public final PositionFunction getHPositionFunction() {
return this.hPositionFunction.get();
}
public final void setHPositionFunction(PositionFunction value) {
this.hPositionFunction.set(value);
}
public final ObjectProperty<PositionFunction> hPositionFunctionProperty() {
return this.hPositionFunction;
}
public final PositionFunction getVPositionFunction() {
return this.vPositionFunction.get();
}
public final void setVPositionFunction(PositionFunction value) {
this.vPositionFunction.set(value);
}
public final ObjectProperty<PositionFunction> vPositionFunctionProperty() {
return this.vPositionFunction;
}
}
double[] points = new double[12];
for (int i = 0; i < 12; i += 2) {
double angle = Math.PI * (0.5 + i / 6d);
points[i] = Math.cos(angle);
points[i + 1] = Math.sin(angle);
}
Polygon polygon = new Polygon(points);
OffsetPane op = new OffsetPane();
double fieldHeight = 100;
double fieldWidth = Math.sqrt(0.75) * fieldHeight;
for (int i = 0; i < 23; i++) {
Button button = new Button();
button.setShape(polygon);
button.setPrefSize(fieldWidth, fieldHeight);
op.getChildren().add(button);
}
// horizontal placement just right of the last element
op.setHPositionFunction((int index, double x, double y, double width, double height) -> new Point2D(x + width, y));
// vertical position half the size left/right depending on index and
// 1/4 the node height above the bottom of the last node
op.setVPositionFunction((int index, double x, double y, double width, double height) -> new Point2D(x + (index % 2 == 0 ? width : -width) / 2, y + height * 0.75));