I am very beginner at JavaFX and im facing this issue: I want to make layout like this: What i need
And this is what i have: enter image description here
It seems that i tried a lot of different layouts and i just cant get it right. I ended up with VBox'es and thats the best i can get. Even though I described "vBox2" size with "PrefSize" to be Half Half of the whole scene, it doesnt react at all.
This is my code:
@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
pane.setLeft(getVBox());
pane.setBottom(getVBox2());
pane.setRight(getVBox3());
// Create a scene and place it in the stage
Scene scene = new Scene(pane, 1000,800);
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;
}
}
I cant use FXML or style it in CSS.
Thank you for any advices.
The general process for a layout pane (such as VBox
or BorderPane
) to layout its child nodes is as follows:
- Query the child nodes for their minimum, maximum, and preferred sizes
Compute the position and size to be allocated to each child node, adhering to its own layout policy, and making a best effort to respect the minimum, preferred, and maximum sizes of the child nodes
Request the child nodes perform their own layout, allocating the sizes calculated to each
It's not always possible to respect all the min/max/pref constraints of the child nodes; e.g. if the sum of the minimum heights of all children of a VBox
is greater than the height of the VBox
itself, there's simply no way to fit all the children in the layout. Conversely, if the height of the VBox
is greater than the sum of all the preferred heights of the children, there will be extra vertical space to be allocated somehow. Most layout panes have settings that configure how to handle these situations: some of these settings apply to the entire layout pane, others are applied on a per-child basis.
The layout policy for a BorderPane
is essentially as follows:
- The
top
andbottom
nodes are allocated the full width of theBorderPane
, and each get their preferred height. These nodes are positioned across the full width of the border pane, at the top and bottom respectively. This is the part that makes theBorderPane
behave differently to the way you require. - The
left
andright
nodes are allocated the full height of theBorderPane
, less the height of thetop
andbottom
nodes, and each get their preferred width. These are positioned at the left and right of the border pane, respectively, below thetop
and above thebottom
nodes. - The
center
node receives all the remaining space.
This is adjusted if the resulting sizes violate minimum or maximum sizes of the nodes, if possible.
So the layout in your image is exactly as expected; vbox2
gets the full width and its preferred height; vbox
gets its preferred width and the remaining height of the border pane, and vbox3
gets the remaining space.
You can basically achieve what you're looking for here by placing vbox
and vbox2
in a VBox
of their own, and placing that VBox
in the left of the border pane; then placing vbox3
in the center (the right would work too):
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); }
}
You haven't specified how you want this to behave on resizing the window, but the "center" region will essentially be more "responsive" than the left.
The initial window looks like: