Reputation: 775
I have a GridPane
inside of a ScrollView
. I'm adding images in each space of the GridPane
. First there is only 1 row and 3 columns. But when I pass the amount of 3 images, I increase the GridPane
in one row and I add the number (130px
) that represents the height of a grid row. So here is my code.
private void AddItem() {
ImageView image = new ImageView();
image.setImage(new Image("media/logo.jpg"));
image.setFitHeight(50);
image.setFitWidth(100);
if (columns > 2) {//when it reaches the end of the columns
viewGrid.setPrefHeight(viewGrid.getHeight() + 130);//I increase the height of the GridPane
viewGrid.addRow(rows++);//I add a new row
columns=0;//I set the column to 0 again
}
viewGrid.add(image, columns, rows);
columns++;
}
The images started to smash into each other instead of keeping the real position:
Is there some property in GridPane
that allows me to achieve the desired behavior?
Upvotes: 1
Views: 6702
Reputation: 82531
Don't manually adjust the size of the GridPane
. Use rowConstraints
instead. Those allow you to specify properties for a row, such as alignment and size constraints. The GridPane
will automatically update it's height.
private static final int COLUMN_COUNT = 3;
private int nextColumnIndex = COLUMN_COUNT;
private int currentRow = -1;
@Override
public void start(Stage primaryStage) {
Image image = new Image("http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a");
GridPane imagePane = new GridPane();
ColumnConstraints colConstraint = new ColumnConstraints(120);
colConstraint.setHalignment(HPos.LEFT);
RowConstraints rowConstraints = new RowConstraints(130);
rowConstraints.setValignment(VPos.CENTER);
// add constraints for columns
imagePane.getColumnConstraints().addAll(colConstraint, colConstraint, colConstraint);
ScrollPane scroll = new ScrollPane(imagePane);
scroll.setFitToWidth(true);
scroll.setPrefSize(380, 300);
BorderPane root = new BorderPane(scroll);
Button btn = new Button("Add Image");
btn.setOnAction((ActionEvent event) -> {
ImageView newImage = new ImageView(image);
newImage.setFitHeight(50);
newImage.setFitWidth(100);
if (nextColumnIndex >= COLUMN_COUNT) {
nextColumnIndex = 0;
currentRow++;
imagePane.getRowConstraints().add(rowConstraints);
}
imagePane.addRow(currentRow, newImage);
nextColumnIndex++;
});
root.setLeft(new VBox(btn));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
By the way: The addRow
method is used to add children to a specific row, not for adding the row itself. A row is automatically added to the GridPane
, if a Node
with the index (or a larger index) is added as child. You need not create a row by calling a GridPane
method.
Note that behaviour similar to the one you're trying to achieve is already implemented in FlowPane
. This would be an option to simplify your code. Just make sure the width of the FlowPane
is chosen appropriately (i.e. allowing 3, but not 4 elements in a row).
@Override
public void start(Stage primaryStage) {
Image image = new Image("http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png?v=c78bd457575a");
FlowPane imagePane = new FlowPane();
imagePane.setHgap(20);
imagePane.setVgap(130 - 50);
imagePane.setRowValignment(VPos.CENTER);
imagePane.setColumnHalignment(HPos.LEFT);
ScrollPane scroll = new ScrollPane(imagePane);
scroll.setFitToWidth(true);
scroll.setPrefSize(380, 300);
BorderPane root = new BorderPane(scroll);
Button btn = new Button("Add Image");
btn.setOnAction((ActionEvent event) -> {
ImageView newImage = new ImageView(image);
newImage.setFitHeight(50);
newImage.setFitWidth(100);
imagePane.getChildren().add(newImage);
});
root.setLeft(new VBox(btn));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
Upvotes: 2