我正在 JavaFx 中创建一个棋盘游戏,它在我的桌面 PC 上运行良好,屏幕分辨率为 1920x1080。当我尝试在我的笔记本电脑(也是 1920x1080,但默认屏幕尺寸为 125%)中打开它时,它不再正确显示元素(它们的尺寸超出了屏幕边界)。使应用程序正常工作的唯一方法是在 1920x1080 屏幕上运行它,默认屏幕尺寸为 100%
我需要一种方法将整个舞台缩放到正确的分辨率
这是我的 Main.java:
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws IOException {
final double WIDTH = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
final double HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
Parent board = FXMLLoader.load(getClass().getResource("/board.fxml"));
Pane innerBoard = ((Pane)board.getChildrenUnmodifiable().get(0));
Assert.assertCmp(innerBoard.getId(), "BOARD");
Scene scene = new Scene(board, WIDTH, HEIGHT);
scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setFullScreen(true);
primaryStage.setResizable(true);
innerBoard.setVisible(false);
primaryStage.setFullScreenExitHint("");
primaryStage.show();
innerBoard.setVisible(true);
}
}
这是 FXML:
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Pane id="BOARD" fx:id="innerBoard" layoutX="356.0" layoutY="-7.0" style="-fx-background-color: #cfffd1;">
<children>
<!-- Lots of children -->
</children>
</Pane>
</children>
</Pane>
我建议您放弃窗格以及数字位置和大小。 您希望您的主板能够以任何分辨率显示; 明确的位置和大小直接与此相矛盾。
布局是使您的电路板适合任何尺寸的最佳方式。
(当然,布局仅适用于矩形板区域;我假设您不会选择复杂的东西,例如圆形或基于六边形的板,或具有蜿蜒路径的板。在这些情况下,Canvas可能是比窗格更好的选择。)
GridPane允许设置RowConstraints和ColumnConstraints,每个都可以基于百分比。 如果行和列的大小是其父级宽度的百分比,则可以免费缩放。 这是大富翁棋盘的一个非常原始的再现:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.Priority;
public class MonopolyBoard
extends Application {
// Source:
// https://commons.wikimedia.org/wiki/File:Store_Building_Flat_Icon_Vector.svg
private static final String SIDE_SPACE_IMAGE_URI =
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/53"
+ "/Store_Building_Flat_Icon_Vector.svg"
+ "/240px-Store_Building_Flat_Icon_Vector.svg.png";
// Source:
// https://commons.wikimedia.org/wiki/File:Car_icon_transparent.png
private static final String CORNER_SPACE_IMAGE_URI =
"https://upload.wikimedia.org/wikipedia/commons/7/7e"
+ "/Car_icon_transparent.png";
@Override
public void start(Stage stage) {
GridPane grid = new GridPane();
Node[] row = new Node[11];
row[0] = createSpace(CORNER_SPACE_IMAGE_URI);
row[10] = createSpace(CORNER_SPACE_IMAGE_URI);
for (int i = 1; i <= 9; i++) {
row[i] = createSpace(SIDE_SPACE_IMAGE_URI);
}
grid.addRow(0, row);
for (int i = 1; i <= 9; i++) {
grid.add(createSpace(SIDE_SPACE_IMAGE_URI), 0, i);
grid.add(createSpace(SIDE_SPACE_IMAGE_URI), 10, i);
}
row[0] = createSpace(CORNER_SPACE_IMAGE_URI);
row[10] = createSpace(CORNER_SPACE_IMAGE_URI);
for (int i = 1; i <= 9; i++) {
row[i] = createSpace(SIDE_SPACE_IMAGE_URI);
}
grid.addRow(10, row);
grid.getColumnConstraints().add(createColumnConstraints(2 / 11.0));
for (int i = 1; i <= 9; i++) {
grid.getColumnConstraints().add(createColumnConstraints(1 / 11.0));
}
grid.getColumnConstraints().add(createColumnConstraints(2 / 11.0));
grid.getRowConstraints().add(createRowConstraints(2 / 11.0));
for (int i = 1; i <= 9; i++) {
grid.getRowConstraints().add(createRowConstraints(1 / 11.0));
}
grid.getRowConstraints().add(createRowConstraints(2 / 11.0));
stage.setScene(new Scene(grid, 50 * 11, 50 * 11));
stage.setTitle("Monopoly");
stage.show();
}
private ColumnConstraints createColumnConstraints(double percentage) {
ColumnConstraints constraints = new ColumnConstraints();
constraints.setPercentWidth(percentage * 100);
constraints.setHgrow(Priority.ALWAYS);
return constraints;
}
private RowConstraints createRowConstraints(double percentage) {
RowConstraints constraints = new RowConstraints();
constraints.setPercentHeight(percentage * 100);
constraints.setVgrow(Priority.ALWAYS);
return constraints;
}
private Node createSpace(String imageURI) {
BorderPane container = new BorderPane();
container.setStyle(
"-fx-border-width: 1px;"
+ " -fx-border-style: solid;"
+ " -fx-background-image: url('" + imageURI + "');"
+ " -fx-background-position: center;"
+ " -fx-background-repeat: no-repeat;"
+ " -fx-background-size: contain;");
return container;
}
public static void main(String[] args) {
launch(args);
}
}
除了使用 RowConstraints 和 ColumnConstraints 的百分比属性之外,上面的代码还利用了 CSS 图像缩放功能,使用 -fx-background-size: contain。
调整窗口大小(或最大化)以查看缩放效果。 显然,如果是全屏,则将应用相同的缩放比例。