JavaFX setPrefSize 没有改变 vBox 的大小
JavaFX setPrefSize is not changing vBox size
我是 JavaFX 的新手,我正面临这个问题:
我想这样布局:What i need
这就是我所拥有的:enter image description here
看来我尝试了很多不同的布局,但我就是做不好。我最终得到了 VBox'es,那是我能得到的最好的。尽管我将 "vBox2" 大小和 "PrefSize" 描述为整个场景的一半,但它根本没有反应。
这是我的代码:
@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;
}
}
我无法在 CSS 中使用 FXML 或设置样式。
感谢您的任何建议。
我能想到的解决问题的最简单方法是构建两个 HBox 并将 VBox 放在其中。
举个例子:Sebastian Damm 创造了这个简单的:
https://www.javacodegeeks.com/2012/07/javafx-20-layout-panes-hbox-and-vbox.html
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* Created on: 20.03.2012
* @author Sebastian Damm
*/
public class HBoxandVBoxExample extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
HBox hbox = new HBox(50);
hbox.setAlignment(Pos.CENTER); // default TOP_LEFT
VBox vbox1 = new VBox();
vbox1.setAlignment(Pos.BOTTOM_CENTER);
vbox1.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox2 = new VBox(10);
vbox2.setAlignment(Pos.CENTER);
vbox2.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox3 = new VBox(20);
vbox3.setAlignment(Pos.TOP_CENTER);
vbox3.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
for (int i = 0; i < 5; i++)
{
Button bt = new Button("Button " + (i+1));
Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method
Button bt3 = new Button("Button " + (i+1));
vbox1.getChildren().add(bt);
vbox2.getChildren().add(bt2);
vbox3.getChildren().add(bt3);
}
hbox.getChildren().addAll(vbox1, vbox2, vbox3);
Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node
primaryStage.setTitle("HBox and VBox Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}
布局窗格(例如VBox
或BorderPane
)布局其child节点的一般过程如下:
- 查询 child 个节点的最小值、最大值和首选
尺码
计算分配给每个的位置和大小child
节点,坚持自己的布局策略,并尽最大努力
遵守 child 节点
的最小、首选和最大大小
请求child节点执行自己的布局,分配
尺寸计算到每个
并不总是能够遵守 child 节点的所有 min/max/pref 约束;例如如果一个VBox
的所有children的最小高度之和大于VBox
本身的高度,根本就没有办法容纳所有的children在布局中。相反,如果 VBox
的高度大于 children 的所有首选高度的总和,则会有额外的垂直 space 以某种方式分配。大多数布局窗格都有配置如何处理这些情况的设置:其中一些设置适用于整个布局窗格,其他设置在 per-child 基础上应用。
BorderPane
的布局策略基本上如下:
-
top
和 bottom
节点分配了 BorderPane
的整个宽度,并且每个节点都获得了它们的首选高度。这些节点位于边框窗格的整个宽度上,分别位于顶部和底部。 这是使 BorderPane
的行为与您要求的方式不同的部分。
-
left
和 right
节点分配了 BorderPane
的全高,减去 top
和 bottom
节点的高度,并且每个人都有自己喜欢的宽度。它们位于边框窗格的左侧和右侧,分别位于 top
节点下方和 bottom
节点上方。
center
节点接收所有剩余的space。
如果可能的话,如果生成的大小违反节点的最小或最大大小,则会对此进行调整。
所以您图片中的布局完全符合预期; vbox2
获取全宽及其首选高度; vbox
获取其首选宽度和边框窗格的剩余高度,vbox3
获取剩余的 space。
通过将 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); }
}
您还没有指定在调整 window 大小时您希望它如何表现,但是 "center" 区域基本上会比左边 "responsive" 大。
最初的 window 看起来像:
我是 JavaFX 的新手,我正面临这个问题: 我想这样布局:What i need
这就是我所拥有的:enter image description here
看来我尝试了很多不同的布局,但我就是做不好。我最终得到了 VBox'es,那是我能得到的最好的。尽管我将 "vBox2" 大小和 "PrefSize" 描述为整个场景的一半,但它根本没有反应。
这是我的代码:
@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;
}
}
我无法在 CSS 中使用 FXML 或设置样式。
感谢您的任何建议。
我能想到的解决问题的最简单方法是构建两个 HBox 并将 VBox 放在其中。 举个例子:Sebastian Damm 创造了这个简单的: https://www.javacodegeeks.com/2012/07/javafx-20-layout-panes-hbox-and-vbox.html
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* Created on: 20.03.2012
* @author Sebastian Damm
*/
public class HBoxandVBoxExample extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
HBox hbox = new HBox(50);
hbox.setAlignment(Pos.CENTER); // default TOP_LEFT
VBox vbox1 = new VBox();
vbox1.setAlignment(Pos.BOTTOM_CENTER);
vbox1.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox2 = new VBox(10);
vbox2.setAlignment(Pos.CENTER);
vbox2.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
VBox vbox3 = new VBox(20);
vbox3.setAlignment(Pos.TOP_CENTER);
vbox3.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: black");
for (int i = 0; i < 5; i++)
{
Button bt = new Button("Button " + (i+1));
Button bt2 = new Button("Button " + (i+1)); // unfortunately there´s no "clone" or "copy" method
Button bt3 = new Button("Button " + (i+1));
vbox1.getChildren().add(bt);
vbox2.getChildren().add(bt2);
vbox3.getChildren().add(bt3);
}
hbox.getChildren().addAll(vbox1, vbox2, vbox3);
Scene scene = new Scene(hbox, 350, 250); // the hbox is the root node
primaryStage.setTitle("HBox and VBox Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}
布局窗格(例如VBox
或BorderPane
)布局其child节点的一般过程如下:
- 查询 child 个节点的最小值、最大值和首选 尺码
计算分配给每个的位置和大小child 节点,坚持自己的布局策略,并尽最大努力 遵守 child 节点
的最小、首选和最大大小
请求child节点执行自己的布局,分配 尺寸计算到每个
并不总是能够遵守 child 节点的所有 min/max/pref 约束;例如如果一个VBox
的所有children的最小高度之和大于VBox
本身的高度,根本就没有办法容纳所有的children在布局中。相反,如果 VBox
的高度大于 children 的所有首选高度的总和,则会有额外的垂直 space 以某种方式分配。大多数布局窗格都有配置如何处理这些情况的设置:其中一些设置适用于整个布局窗格,其他设置在 per-child 基础上应用。
BorderPane
的布局策略基本上如下:
-
top
和bottom
节点分配了BorderPane
的整个宽度,并且每个节点都获得了它们的首选高度。这些节点位于边框窗格的整个宽度上,分别位于顶部和底部。 这是使BorderPane
的行为与您要求的方式不同的部分。 -
left
和right
节点分配了BorderPane
的全高,减去top
和bottom
节点的高度,并且每个人都有自己喜欢的宽度。它们位于边框窗格的左侧和右侧,分别位于top
节点下方和bottom
节点上方。 center
节点接收所有剩余的space。
如果可能的话,如果生成的大小违反节点的最小或最大大小,则会对此进行调整。
所以您图片中的布局完全符合预期; vbox2
获取全宽及其首选高度; vbox
获取其首选宽度和边框窗格的剩余高度,vbox3
获取剩余的 space。
通过将 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); }
}
您还没有指定在调整 window 大小时您希望它如何表现,但是 "center" 区域基本上会比左边 "responsive" 大。
最初的 window 看起来像: