当我遇到以下问题时,我试图使用GridPane
来布局JavaFX阶段。如果我使用适当的约束设置网格并向其添加新实例化的StackPane
,则场景,阶段及其内容的默认大小确保内容可见:
但是,如果我在将新实例化的StackPane
添加到GridPane
之前添加指定边框的JavaFX CSS样式,那么事情的默认大小似乎已完全崩溃:
我的代码如下:
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()
的执行顺序会产生影响?
谢谢!
答案 0 :(得分:2)
问题是什么
你的例子有点含糊不清。您无需随时设置添加到舞台的任何内容的首选大小。因此,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上设置适当的约束来从上到下的角度完成类似的操作,例如: / p>
gridPane.setPrefSize(300, 200);
注意的
我建议使用JavaFX Application类而不是Platform.startup()调用,除非有充分的理由使用后者(在这种情况下是 - 与Swing接口,如你已在评论中注明了。)