Контейнер javafx.scene.layout.GridPane упорядочивает вложенные элементы в виде таблицы. Для каждого элемента можно задать в какой строке и каком столбце грида он будет располагаться.
Для добавления элементов GridPane определяет свой метод add(), который имеет несколько версий. Некоторые из них:
void add(Node child, int columnIndex, int rowIndex) void add(Node child, int columnIndex, int rowIndex, int colspan, int rowspan)
Оба метода добавляют элемент child в строку с индексом rowIndex и в столбец с индексом columnIndex. Во втором методе параметры colspan и rowspan указывают соответственно, на сколько столбцов и строк надо растягивать элемент.
Например:
GridPane gridpane = new GridPane(); gridpane.add(new Button(), 1, 0); // столбец=1 строка=0 gridpane.add(new Label(), 2, 0); // столбец=2 строка=0
Также для добавления можно использовать стандартный для других панелей компоновки способ - метод getChildren().getAll(), который определен в родительском классе Pane. Но в этом случае все добавляемые элементы будут помещаться в самую первую ячейку. В этом случае мы можем использовать еще ряд методов для установки строки и столбца, в которе помещается элемент:
static void setColumnIndex(Node child, Integer value) // устанавливает столбец static void setColumnSpan(Node child, Integer value) // устанавливает строку static void setConstraints(Node child, int columnIndex, int rowIndex) // устанавливает столбец и строку
Установка столбца и строки для добавляемых элементов:
GridPane gridpane = new GridPane(); Button button = new Button(); GridPane.setRowIndex(button, 0); // строка=0 GridPane.setColumnIndex(button, 1); // столбец=1 Label label = new Label(); GridPane.setConstraints(label, 2, 0); // столбец=2 строка=0
По умолчанию строки и столбцы масштабируются таким образом, чтобы вместить помещенные в них элементы. По умолчанию столбцы расширяются до ширины самого широкого элемента, а высота строк соответствует высоте самого высокого элемента. Однако нередко такое поведение не является желательным, и в этом случе мы можем настроить размеры строк и столбцов.
С помощью метода getColumnConstraints() можно получить коллекцию определений столбцов в виде объекта
ObservableList<ColumnConstraints>
. Определение столбца представляет класс javafx.scene.layout.ColumnConstraints.
Чтобы создать определение столбца, можно использовать один из следующих конструкторов:
ColumnConstraints()
ColumnConstraints(double width): создает столбец с фиксированной шириной
ColumnConstraints(double minWidth, double prefWidth, double maxWidth): создает столбец с фиксированными значениями минимальной, предпочтительной и максимальной ширины
ColumnConstraints(double minWidth, double prefWidth, double maxWidth, Priority hgrow, HPos halignment, boolean fillWidth): создает столбец с фиксированными значениями минимальной, предпочтительной и максимальной ширины, hgrow устанавливает параметры расширения столбца, halignment устанавливает выравнивание по горизонали, а fillWidth при значении true задает растяжение элемента до границ столбца
Добавление в грид двух столбцов с фиксированными размерами:
GridPane grid = new GridPane(); grid.getColumnConstraints().add(new ColumnConstraints(100)); // столбец с шириной от 0 до 100 grid.getColumnConstraints().add(new ColumnConstraints(200)); // столбец с шириной от 0 до 200
Однако при задании фиксированной ширины мы можем столкнуться с проблемой, что если окно приложения начнет растягиваться, то столбцы сохранят свои размеры. В итоге некоторая часть пространства останется незанятой:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Label first = new Label("First"); Label second = new Label("Second"); Label third = new Label("Third"); GridPane root = new GridPane(); root.getColumnConstraints().add(new ColumnConstraints(80)); root.getColumnConstraints().add(new ColumnConstraints(150)); root.getColumnConstraints().add(new ColumnConstraints(70)); root.setGridLinesVisible(true); // делаем видимой сетку строк и столбцов root.setColumnIndex(first, 0); root.setColumnIndex(second, 1); root.setColumnIndex(third, 2); root.getChildren().addAll(first, second, third); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }
Чтобы отобразить границы строк и столбцов вызывается метод root.setGridLinesVisible(true)
.
Пример растягивания окна при фиксированной ширине столбцов:
В этом случае с помощью перечисления Priority можно настроить параметры растягивания столбца:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.Priority; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Label first = new Label("First"); Label second = new Label("Second"); Label third = new Label("Third"); GridPane root = new GridPane(); root.getColumnConstraints().add(new ColumnConstraints(80)); ColumnConstraints column2 = new ColumnConstraints(150,150,Double.MAX_VALUE); column2.setHgrow(Priority.ALWAYS); root.getColumnConstraints().add(column2); ColumnConstraints column3 = new ColumnConstraints(70,70,Double.MAX_VALUE); column3.setHgrow(Priority.ALWAYS); root.getColumnConstraints().add(column3); root.setGridLinesVisible(true); root.setColumnIndex(first, 0); root.setColumnIndex(second, 1); root.setColumnIndex(third, 2); root.getChildren().addAll(first, second, third); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }
В данном случае при растяжении окна приложения автоматически будут растягиваться второй и третий столбцы.
С помощью метода getRowConstraints() у объекта GridPane можно получить коллекцию определений строк в виде объекта
ObservableList<RowConstraints>
. Определение строк в GridPane представляют класс javafx.scene.layout.RowConstraints.
Чтобы создать определение строки, можно использовать один из следующих конструкторов:
RowConstraints()
RowConstraints(double height): создает строку с фиксированной высотоой
RowConstraints(double minHeight, double prefHeight, double maxHeight): создает строку с фиксированными значениями минимальной, предпочтительной и максимальной высоты
RowConstraints(double minHeight, double prefHeight, double maxHeight, Priority vgrow, VPos valignment, boolean fillHeight): создает строку с фиксированными значениями минимальной, предпочтительной и максимальной высоты, vgrow устанавливает параметры расширения строки, valignment устанавливает выравнивание по вертикали, а fillWidth при значении true задает растяжение элемента по всей высоте строки
Как и столбец, строка по умолчанию занимает столько места, сколько необходимо для вмещения ее содержимого:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.Priority; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.RowConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Label first = new Label("First"); Label second = new Label("Second"); Label third = new Label("Third"); Label sixth = new Label("Sixth"); GridPane root = new GridPane(); // определения столбцов root.getColumnConstraints().add(new ColumnConstraints(80)); ColumnConstraints column2 = new ColumnConstraints(150, 150, Double.MAX_VALUE); column2.setHgrow(Priority.ALWAYS); root.getColumnConstraints().add(column2); ColumnConstraints column3 = new ColumnConstraints(70, 70, Double.MAX_VALUE); column3.setHgrow(Priority.ALWAYS); root.getColumnConstraints().add(column3); // определения строк root.getRowConstraints().add(new RowConstraints(80)); root.getRowConstraints().add(new RowConstraints(80)); root.setGridLinesVisible(true); root.add(first, 0, 0); root.add(second, 1, 0); root.add(third, 2, 0); root.add(sixth, 2, 1); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }
Чтобы растянуть строки по всей ширине GridPane, нужно установить для них ограничение vgrow с помощью перечисления Priority и метода setVgrow():
// определения строк RowConstraints row1 = new RowConstraints(80, 80, Double.MAX_VALUE); row1.setVgrow(Priority.ALWAYS); RowConstraints row2 = new RowConstraints(80, 80, Double.MAX_VALUE); row2.setVgrow(Priority.ALWAYS); root.getRowConstraints().add(row1); root.getRowConstraints().add(row2);
Для столбцов с помощью метода setPercentWidth() можно установить, сколько процентов обзего пространства будет занимать данный столбец. Аналогично для строк с помощью метода setPercentHeight() можно установить, какую долю пространства контейнера бует занимать строка. То есть вместо фиксированных размеров использовать пропорциональные:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.Priority; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.RowConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Label first = new Label("First"); Label second = new Label("Second"); Label third = new Label("Third"); Label sixth = new Label("Sixth"); GridPane root = new GridPane(); // определения столбцов ColumnConstraints column1 = new ColumnConstraints(); column1.setPercentWidth(30); root.getColumnConstraints().add(column1); ColumnConstraints column2 = new ColumnConstraints(); column2.setPercentWidth(40); root.getColumnConstraints().add(column2); ColumnConstraints column3 = new ColumnConstraints(); column3.setPercentWidth(30); root.getColumnConstraints().add(column3); // определения строк RowConstraints row1 = new RowConstraints(); row1.setPercentHeight(55); root.getRowConstraints().add(row1); RowConstraints row2 = new RowConstraints(); row2.setPercentHeight(45); root.getRowConstraints().add(row2); root.setGridLinesVisible(true); root.add(first, 0, 0); root.add(second, 1, 0); root.add(third, 2, 0); root.add(sixth, 2, 1); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }
Но если совокупная сумма процентов окажется больше 100, например, есть 3 столбца, и для каждого из них установлена ширина в 50 процентов, тогда каждый столбец будет занимать 1/3 пространства (50/(50+50+50)).
По умолчанию элементы занимают только то пространство, которое им необходимо:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.RowConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Button first = new Button("First"); Button second = new Button("Second"); Button third = new Button("Third"); Button fourth = new Button("Fourth"); GridPane root = new GridPane(); ColumnConstraints column1 = new ColumnConstraints(); column1.setPercentWidth(50); root.getColumnConstraints().add(column1); ColumnConstraints column2 = new ColumnConstraints(); column2.setPercentWidth(50); root.getColumnConstraints().add(column2); RowConstraints row1 = new RowConstraints(); row1.setPercentHeight(50); root.getRowConstraints().add(row1); RowConstraints row2 = new RowConstraints(); row2.setPercentHeight(50); root.getRowConstraints().add(row2); root.setGridLinesVisible(true); root.add(first, 0, 0); root.add(second, 0, 1); root.add(third, 1, 0); root.add(fourth, 1, 1); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }
Как мы видим, из скриншота, элементы позиционируются слева по горизонтали и по центру по вертикали. Но с помощью ряда статических методов GridPane можно настроить положение элемента:
static void setHalignment(Node child, HPos value)
: устанавливает горизонтальное выравнивание для элемента child
static void setHgrow(Node child, Priority value)
: устанавливает, как элемент child будет растягиваться по горизонтали
static void setMargin(Node child, Insets value)
: устанавливает для элемента child отступы от границ контейнера
static void setValignment(Node child, VPos value)
: устанавливает вертикальное выравнивание для элемента child
static void setVgrow(Node child, Priority value)
: устанавливает, как элемент child будет растягиваться по вертикали
Применим эти методы:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.geometry.Insets; import javafx.scene.layout.Priority; import javafx.geometry.HPos; import javafx.geometry.VPos; import javafx.scene.layout.GridPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.RowConstraints; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Button first = new Button("First"); // расположем кнопку в нижнем правом углу GridPane.setHalignment(first, HPos.RIGHT); GridPane.setValignment(first, VPos.BOTTOM); Button second = new Button("Second"); // растянем кнопку по горизонтали second.setMaxWidth(Double.MAX_VALUE); GridPane.setHgrow(second, Priority.ALWAYS); Button third = new Button("Third"); // растянем кнопку по горизонтали и вертикали third.setMaxWidth(Double.MAX_VALUE); third.setMaxHeight(Double.MAX_VALUE); GridPane.setHgrow(third, Priority.ALWAYS); GridPane.setVgrow(third, Priority.ALWAYS); Button fourth = new Button("Fourth"); // кнопка заполняет все пространство ячейки fourth.setMaxWidth(Double.MAX_VALUE); fourth.setMaxHeight(Double.MAX_VALUE); GridPane.setHgrow(fourth, Priority.ALWAYS); GridPane.setVgrow(fourth, Priority.ALWAYS); // установим отступ в 10 единиц GridPane.setMargin(fourth, new Insets(10)); GridPane root = new GridPane(); ColumnConstraints column1 = new ColumnConstraints(); column1.setPercentWidth(50); root.getColumnConstraints().add(column1); ColumnConstraints column2 = new ColumnConstraints(); column2.setPercentWidth(50); root.getColumnConstraints().add(column2); RowConstraints row1 = new RowConstraints(); row1.setPercentHeight(50); root.getRowConstraints().add(row1); RowConstraints row2 = new RowConstraints(); row2.setPercentHeight(50); root.getRowConstraints().add(row2); root.setGridLinesVisible(true); root.add(first, 0, 0); root.add(second, 0, 1); root.add(third, 1, 0); root.add(fourth, 1, 1); Scene scene = new Scene(root, 300, 200); stage.setScene(scene); stage.setTitle("GridPane in JavaFX"); stage.show(); } }