Is there any way in JavaFX to take best from both TilePane or FlowPane and GridPane?
Here\'s what I\'d like to achieve:
First, I like the idea
Exactly for the purpose you are describing, I created the ButtonGridPane
. It's a first draft, and there is still room for improvement, but maybe it can give you a basic idea.
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 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;
}
}