在 GridPane 内容上指定 JavaFX CSS 边框是否应该折叠大小?
Is specifying JavaFX CSS borders on GridPane contents supposed to collapse the sizing?
当我 运行 遇到以下问题时,我试图使用 GridPane
布局 JavaFX 阶段。如果我使用适当的约束设置网格并向其添加新实例化的 StackPane
,则场景、舞台及其内容的默认大小可确保内容可见:
但是,如果我在将新实例化的 StackPane
添加到 GridPane
之前将指定边框的 JavaFX CSS 样式添加到 GridPane
,那么事物的默认大小似乎会崩溃完成:
我的代码如下:
public static void main(final String[] args) {
Platform.startup(() -> {});
Platform.runLater(() -> {
final GridPane gridPane = new GridPane();
final Scene scene = new Scene(gridPane);
final Stage stage = new Stage();
stage.setScene(scene);
final List<StackPane> panes = new ArrayList<>();
for (int i = 0; i < 4; i++) {
// Create a new pane with a random background color for
// illustration
final StackPane p = createNewPane();
panes.add(p);
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
}
for (int r = 0; r < 2; r++) {
final RowConstraints rc = new RowConstraints();
rc.setPercentHeight(50);
gridPane.getRowConstraints().add(rc);
}
for (int c = 0; c < 2; c++) {
final ColumnConstraints cc = new ColumnConstraints();
cc.setPercentWidth(50);
gridPane.getColumnConstraints().add(cc);
}
for (int r = 0, i = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
gridPane.add(panes.get(i++), c, r);
}
}
stage.show();
});
}
奇怪的是,如果我在设置场景后将 stage.show()
移到右侧,那么即使使用 CSS 也一切正常。
任何人都可以帮助我理解,第一,这是否是预期的行为,第二,为什么 stage.show()
的执行顺序会有所不同?
谢谢!
问题是什么
你的例子有点含糊。您不会随时设置添加到舞台的任何内容的首选大小。因此,JavaFX 平台真的可以在调整大小方面做任何它想做的事情。设置首选百分比大小与设置首选绝对大小不同。百分比大小是相对的,所以问题就变成了,相对于什么?答案尚不清楚。
至于为什么会这样:
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
我说不准。我的猜测是 CSS 的使用会触发一些额外的布局逻辑,这些逻辑会在没有任何大小提示的情况下影响调整大小。
如何修复
无论如何,解决方案只是让事情变得更清楚,并至少为应用程序中的某些内容指定首选大小,然后应用程序最初将调整为该首选大小。
这是一个例子:
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Starter {
public static void main(String[] args) {
Platform.startup(() -> {});
Platform.runLater(() -> {
final GridPane gridPane = new GridPane();
final Scene scene = new Scene(gridPane);
final Stage stage = new Stage();
stage.setScene(scene);
final List<StackPane> panes = new ArrayList<>();
for (int i = 0; i < 4; i++) {
// Create a new pane with a random background color for
// illustration
final StackPane p = createNewPane();
panes.add(p);
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
}
for (int r = 0; r < 2; r++) {
final RowConstraints rc = new RowConstraints();
rc.setPercentHeight(50);
gridPane.getRowConstraints().add(rc);
}
for (int c = 0; c < 2; c++) {
final ColumnConstraints cc = new ColumnConstraints();
cc.setPercentWidth(50);
gridPane.getColumnConstraints().add(cc);
}
for (int r = 0, i = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
gridPane.add(panes.get(i++), c, r);
}
}
stage.show();
});
}
private static final Random random = new Random(42);
private static StackPane createNewPane() {
StackPane pane = new StackPane();
pane.setBackground(
new Background(
new BackgroundFill(
randomColor(), null, null
)
)
);
pane.setPrefSize(150, 100);
return pane;
}
private static Color randomColor() {
return Color.rgb(
random.nextInt(256),
random.nextInt(256),
random.nextInt(256)
);
}
}
解决方案的关键部分是调用:
pane.setPrefSize(150, 100);
设置放置在布局中的堆栈窗格的首选大小。
或者,不是通过在每个 StackPanes 上设置首选大小来进行自下而上的首选大小调整,您也可以通过在 GridPane 上设置适当的约束来从自上而下的角度完成类似的事情,例如:
gridPane.setPrefSize(300, 200);
备注
我建议使用 JavaFX Application class instead of Platform.startup() 调用,除非确实有充分的理由使用后者(在本例中是这样的——与 Swing 接口,正如您在评论中指出的那样)。
当我 运行 遇到以下问题时,我试图使用 GridPane
布局 JavaFX 阶段。如果我使用适当的约束设置网格并向其添加新实例化的 StackPane
,则场景、舞台及其内容的默认大小可确保内容可见:
但是,如果我在将新实例化的 StackPane
添加到 GridPane
之前将指定边框的 JavaFX CSS 样式添加到 GridPane
,那么事物的默认大小似乎会崩溃完成:
我的代码如下:
public static void main(final String[] args) {
Platform.startup(() -> {});
Platform.runLater(() -> {
final GridPane gridPane = new GridPane();
final Scene scene = new Scene(gridPane);
final Stage stage = new Stage();
stage.setScene(scene);
final List<StackPane> panes = new ArrayList<>();
for (int i = 0; i < 4; i++) {
// Create a new pane with a random background color for
// illustration
final StackPane p = createNewPane();
panes.add(p);
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
}
for (int r = 0; r < 2; r++) {
final RowConstraints rc = new RowConstraints();
rc.setPercentHeight(50);
gridPane.getRowConstraints().add(rc);
}
for (int c = 0; c < 2; c++) {
final ColumnConstraints cc = new ColumnConstraints();
cc.setPercentWidth(50);
gridPane.getColumnConstraints().add(cc);
}
for (int r = 0, i = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
gridPane.add(panes.get(i++), c, r);
}
}
stage.show();
});
}
奇怪的是,如果我在设置场景后将 stage.show()
移到右侧,那么即使使用 CSS 也一切正常。
任何人都可以帮助我理解,第一,这是否是预期的行为,第二,为什么 stage.show()
的执行顺序会有所不同?
谢谢!
问题是什么
你的例子有点含糊。您不会随时设置添加到舞台的任何内容的首选大小。因此,JavaFX 平台真的可以在调整大小方面做任何它想做的事情。设置首选百分比大小与设置首选绝对大小不同。百分比大小是相对的,所以问题就变成了,相对于什么?答案尚不清楚。
至于为什么会这样:
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
我说不准。我的猜测是 CSS 的使用会触发一些额外的布局逻辑,这些逻辑会在没有任何大小提示的情况下影响调整大小。
如何修复
无论如何,解决方案只是让事情变得更清楚,并至少为应用程序中的某些内容指定首选大小,然后应用程序最初将调整为该首选大小。
这是一个例子:
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Starter {
public static void main(String[] args) {
Platform.startup(() -> {});
Platform.runLater(() -> {
final GridPane gridPane = new GridPane();
final Scene scene = new Scene(gridPane);
final Stage stage = new Stage();
stage.setScene(scene);
final List<StackPane> panes = new ArrayList<>();
for (int i = 0; i < 4; i++) {
// Create a new pane with a random background color for
// illustration
final StackPane p = createNewPane();
panes.add(p);
// The addition / removal of the following line affects the
// layout.
p.setStyle("-fx-border-width:2px;-fx-border-color:red");
}
for (int r = 0; r < 2; r++) {
final RowConstraints rc = new RowConstraints();
rc.setPercentHeight(50);
gridPane.getRowConstraints().add(rc);
}
for (int c = 0; c < 2; c++) {
final ColumnConstraints cc = new ColumnConstraints();
cc.setPercentWidth(50);
gridPane.getColumnConstraints().add(cc);
}
for (int r = 0, i = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
gridPane.add(panes.get(i++), c, r);
}
}
stage.show();
});
}
private static final Random random = new Random(42);
private static StackPane createNewPane() {
StackPane pane = new StackPane();
pane.setBackground(
new Background(
new BackgroundFill(
randomColor(), null, null
)
)
);
pane.setPrefSize(150, 100);
return pane;
}
private static Color randomColor() {
return Color.rgb(
random.nextInt(256),
random.nextInt(256),
random.nextInt(256)
);
}
}
解决方案的关键部分是调用:
pane.setPrefSize(150, 100);
设置放置在布局中的堆栈窗格的首选大小。
或者,不是通过在每个 StackPanes 上设置首选大小来进行自下而上的首选大小调整,您也可以通过在 GridPane 上设置适当的约束来从自上而下的角度完成类似的事情,例如:
gridPane.setPrefSize(300, 200);
备注
我建议使用 JavaFX Application class instead of Platform.startup() 调用,除非确实有充分的理由使用后者(在本例中是这样的——与 Swing 接口,正如您在评论中指出的那样)。