Общий процесс для панели макета (такой как VBox
или BorderPane
) для размещения дочерних узлов выглядит следующим образом:
- Запросите у дочерних узлов их минимальный, максимальный и предпочтительные размеры
Вычислить позицию и размер, который будет выделен для каждого дочернего узла, придерживаясь его собственной политики компоновки и прилагая все усилия для соблюдения минимального, предпочтительного и максимального размеров дочерних узлов
Запросить, чтобы дочерние узлы выполнили свой собственный макет, выделив размеры, рассчитанные для каждого
Не всегда возможно соблюдать все мин / макс / pref ограничения дочерних узлов; например, если сумма минимальных высот всех дочерних элементов VBox
больше, чем высота самого VBox
, просто невозможно разместить всех дочерних элементов в макете. И наоборот, если высота VBox
больше, чем сумма всех предпочтительных высот дочерних элементов, будет как-то выделено дополнительное вертикальное пространство. Большинство панелей макета имеют параметры, которые настраивают, как обрабатывать такие ситуации: некоторые из этих параметров применяются ко всей панели макета, другие применяются для каждого ребенка.
Политика макета для BorderPane
по существу следующим образом:
- Узлам
top
и bottom
выделяется полная ширина BorderPane
, и каждый получает свою предпочтительную высоту. Эти узлы расположены по всей ширине панели границ, сверху и снизу соответственно. Это та часть, которая заставляет BorderPane
вести себя не так, как вам нужно. - Узлам
left
и right
выделяется полная высота BorderPane
, меньше высота узлов top
и bottom
, и каждый получает свою предпочтительную ширину. Они расположены слева и справа от границы, соответственно, ниже top
и выше bottom
узлов. - Узел
center
получает все оставшееся пространство.
Это корректируется, если результирующие размеры нарушают минимальный или максимальный размеры узлов, если это возможно.
Таким образом, компоновка вашего изображения точно соответствует ожидаемой; vbox2
получает полную ширину и предпочитаемую высоту; vbox
получает предпочитаемую ширину и оставшуюся высоту панели границы, а vbox3
получает оставшееся пространство.
Вы можете в основном добиться того, что вы ищете здесь, поместив vbox
и vbox2
в VBox
их собственных, и поместив это VBox
слева от панели границ; затем поместите vbox3
в центр (правое тоже сработало бы):
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Layout extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a border pane
BorderPane pane = new BorderPane();
// Place nodes in the pane
VBox left = new VBox(getVBox(), getVBox2());
pane.setLeft(left);
pane.setCenter(getVBox3());
// Create a scene and place it in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowHBoxVBox"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
private VBox getVBox() {
VBox vBox = new VBox(15);
vBox.setPadding(new Insets(15, 5, 5, 5));
vBox.getChildren().add(new Label("vbox"));
Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
new Label("CSCI 2410"), new Label("CSCI 3720")};
for (Label course : courses) {
VBox.setMargin(course, new Insets(0, 0, 0, 15));
vBox.getChildren().add(course);
}
vBox.setStyle("-fx-border-style: solid inside;");
vBox.setPrefSize(500, 400);
return vBox;
}
private VBox getVBox2() {
VBox vBox2 = new VBox(15);
vBox2.setPadding(new Insets(15, 5, 5, 5));
vBox2.getChildren().add(new Label("Vbox2"));
Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
new Label("CSCI 2410"), new Label("CSCI 3720")};
for (Label course : courses) {
VBox.setMargin(course, new Insets(5, 5, 5, 15));
vBox2.getChildren().add(course);
}
vBox2.setStyle("-fx-border-style: solid inside;");
vBox2.setPrefSize(500, 400);
return vBox2;
}
private VBox getVBox3() {
VBox vBox3 = new VBox(15);
vBox3.setPadding(new Insets(15, 5, 5, 5));
vBox3.getChildren().add(new Label("vbox3"));
Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
new Label("CSCI 2410"), new Label("CSCI 3720")};
for (Label course : courses) {
VBox.setMargin(course, new Insets(0, 0, 0, 15));
vBox3.getChildren().add(course);
}
vBox3.setStyle("-fx-border-style: solid inside;");
vBox3.setPrefSize(500, 800);
return vBox3;
}
public static void main(String[] args) { Application.launch(args); }
}
Вы не указали, как вы будете себя вести при изменении размера окна, но область "center" по существу будет более «отзывчивый», чем левый.
Исходное окно выглядит так: