Как стать автором
Обновить

Учебник по JavaFX: основные макеты

Время на прочтение5 мин
Количество просмотров25K
Автор оригинала: Vojtech Ruzicka
Перевод статьи «JavaFX Tutorial: Basic layouts» автора Vojtech Ruzicka.

Как организовать и разместить GUI компоненты в приложении JavaFX.

Это четвертая статья в серии о JavaFX. В предыдущей статье я описал, как использовать FXML и SceneBuilder для создания вашего пользовательского интерфейса. Теперь мы рассмотрим макеты.

Все посты в серии о JavaFX:

  1. Учебник по JavaFX: начало работы
  2. Учебник по JavaFX: Привет, мир!
  3. Учебник по JavaFX: FXML и SceneBuilder
  4. Учебник по JavaFX: основные макеты
  5. Учебник по JavaFX: расширенные макеты
  6. Учебник по JavaFX: CSS стилизация
  7. JavaFX Weaver: интеграция JavaFX и Spring Boot приложения

Макеты


Макет (Layout) является контейнером для компонентов. Макеты полезны тем, что вы можете позиционировать этот контейнер как целое независимо от того, какие компоненты находятся внутри. Более того, каждая сцена может содержать только один компонент, поэтому вам нужен макет в качестве корневого компонента для вашей сцены, чтобы вы могли разместить все необходимые компоненты сцены. Конечно, одного макета обычно недостаточно, но вы можете поместить один макет внутрь другого.

В дополнение к этому макеты также организуют и размещают ваши компоненты внутри себя. В зависимости от используемого макета дочерние компоненты могут быть расположены:

  • Один за другим по горизонтали
  • Один за другим по вертикали
  • Друг над другом как стек
  • В сетке

Есть еще много вариантов. Важно то, что макет автоматически обновляет положение своих дочерних элементов при изменении его размера. Таким образом, можно иметь согласованный макет, даже при изменении размера окна приложения пользователем.

HBox


Это один из самых простых среди имеющихся макетов. Он просто помещает все предметы по горизонтали в ряд, один за другим, слева направо.



В FXML вы можете использовать HBox следующим образом:

<HBox>
    <Button>1</Button>
    <Button>2</Button>
    <Button>3</Button>
    <Button>4</Button>
</HBox>

В Java вы можете использовать этот код:

HBox hbox = new HBox();
Button btn1 = new Button("1");
Button btn2 = new Button("2");
Button btn3 = new Button("3");
Button btn4 = new Button("4");
hbox.getChildren().addAll(btn1, btn2, btn3, btn4);

Spacing


Наши элементы теперь аккуратно разложены в ряд, один за другим:



Однако такой вариант не очень хорош, так как элементы расположены друг за другом без промежутков. К счастью, мы можем определить промежуток между компонентами, используя свойство spacing HBox:

<HBox spacing="10">
     ...
</HBox>

Или в Java с помощью setSpacing():

HBox hbox = new HBox();
hbox.setSpacing(10);

Padding


Элементы теперь расположены правильно, однако между элементами и самим HBox по-прежнему нет отступов. Может быть полезно добавить Padding (заполнение) в наш HBox:



Вы можете указать каждую область для заполнения отдельно — верхняя, нижняя, левая и правая.

<HBox>
    <padding>
        <Insets top="10" bottom="10" left="10" right="10"/>
    </padding>
    ...
</HBox>

То же самое может быть сделано в Java:

HBox hbox = new HBox();
hbox.setPadding(new Insets(10, 10, 10, 10));

VBox


VBox очень похож на HBox, но вместо того, чтобы отображать внутренние компоненты по горизонтали друг за другом, он отображает их вертикально в столбец:



Вы по-прежнему можете устанавливать свойства spacing и padding так же, как в HBox.

В коде VBox используется точно так же, как HBox, только имя другое:

<VBox spacing="10">
    <padding>
        <Insets top="10" bottom="10" left="10" right="10"/>
    </padding>
    <Button>1</Button>
    <Button>2</Button>
    <Button>3</Button>
    <Button>4</Button>
</VBox>

И на Java:

VBox vbox = new VBox();
vbox.setPadding(new Insets(10, 10, 10, 10));
vbox.setSpacing(10);
Button btn1 = new Button("1");
Button btn2 = new Button("2");
Button btn3 = new Button("3");
Button btn4 = new Button("4");
vbox.getChildren().addAll(btn1, btn2, btn3, btn4);

StackPane


Этот макет полезен для размещения его компонентов друг над другом. Порядок вставки определяет порядок элементов. Это означает, что первый элемент находится внизу, следующий — сверху, и так далее.

Это может быть полезно, например, для того, чтобы в макете показать рисунок и поверх него отобразить какой-либо текст или кнопку.



В следующем примере используется StackPane в FXML:

<StackPane>
    <ImageView>
        <Image url="/image.jpg"/>
    </ImageView>
    <Button>Click Me!</Button>
</StackPane>

Тот же пример на Java:

StackPane stackPane = new StackPane();
Image image = new Image(getClass().getResourceAsStream("/image.jpg"));
ImageView imageView = new ImageView(image);
Button btn = new Button("Click Me!");
stackPane.getChildren().addAll(imageView, btn);

Выравнивание элементов


Вы можете установить выравнивание элементов в стеке, чтобы лучше организовать их расположение:

<StackPane alignment="BOTTOM_CENTER">
 ...
</StackPane>

Конечно, вы можете сделать то же самое в Java:

StackPane stackPane = new StackPane();
stackPane.setAlignment(Pos.BOTTOM_CENTER);

Margin


Если вы хотите еще более детально контролировать расположение элементов, вы можете установить поля (margin) для отдельных элементов в стеке:

<StackPane alignment="BOTTOM_CENTER">
    <ImageView>
        <Image url="/image.jpg"/>
    </ImageView>
    <Button>
        <StackPane.margin>
            <Insets bottom="10"/>
        </StackPane.margin>
        Click Me!
    </Button>
</StackPane>

Или на Java:

StackPane stackPane = new StackPane();
Button btn = new Button("Click Me!");
stackPane.getChildren().add(btn);
StackPane.setMargin(btn, new Insets(0,0,10,0));

FlowPane


Панель Flow может работать в двух режимах — горизонтальном (по умолчанию) или вертикальном.

В горизонтальном режиме элементы отображаются горизонтально, один за другим, как в HBox. Разница в том, что, когда горизонтального пространства больше нет, оно переносится в следующий ряд под первым и продолжается снова. Таким образом, может быть много строк, а не только один, как в HBox.

Вертикальный режим очень похож, но (подобно VBox) он отображает элементы вертикально, сверху вниз. Когда места больше нет, он добавляет еще один столбец и продолжает.

Следующий рисунок иллюстрирует эти два режима:



Заметим, что элементы не обязательно должны иметь такой же размер, как на изображении выше.

Обратите внимание, как пересчитывается положение компонентов, если вы измените размер контейнера:



Вы можете установить внутреннее заполнение этого макета так же, как для HBox и VBox. Однако использование свойства spacing немного отличается. Вместо одного свойства для spacing, вам нужно иметь отдельные горизонтальные и вертикальные свойства spacing, так как элементы могут отображаться в нескольких строках / столбцах. Для горизонтального свойства spacing используйте hgap, для вертикального — vgap.

FlowPane flowPane = new FlowPane();
flowPane.setOrientation(Orientation.VERTICAL);
flowPane.setVgap(10);
flowPane.setHgap(10);
flowPane.getChildren().addAll(...);

Пример FlowPane в FXML:

<FlowPane hgap="10" vgap="10" orientation="VERTICAL">
  ...
</FlowPane>

TilePane


Этот макет очень похож на FlowPane. Его способ отображения компонент практически идентичен. Вы все еще можете использовать горизонтальный или вертикальный режим и определять vgap и hgap.

Одно из важных различий заключается в размерах клеток. FlowPane назначает только пространство, необходимое для каждого компонента. TilePane, с другой стороны, делает размер всех ячеек одинаковым в зависимости от самого большого элемента. Таким образом, все элементы управления хорошо выровнены в строках / столбцах.



На изображении выше одинаковые компоненты размещены одинаковым образом, но вы легко можете заметить разницу.

FlowPane размещает элементы управления один за другим, без лишних интервалов
TilePane помещает элементы управления в ячейки одинакового размера на основе самого большого элемента.

Создание TilePane ничем не отличается от FlowPane, за исключением названия.

<TilePane vgap="10" hgap="10" orientation="VERTICAL" >

То же самое на Java:

TilePane tilePane = new TilePane();
tilePane.setVgap(10);
tilePane.setHgap(10);
tilePane.setOrientation(Orientation.VERTICAL);

Что дальше


В статье было рассмотрено использование нескольких основных макетов для размещения компонентов в JavaFX приложении. В действительности, в JavaFX имеется значительно более разнообразный выбор макетов. Расширенные варианты макетов будут рассмотрены в следующей статье.
Теги:
Хабы:
Всего голосов 5: ↑5 и ↓0+5
Комментарии2

Публикации

Истории

Работа

Java разработчик
331 вакансия

Ближайшие события