Dae*_*guy 3 java user-interface chess javafx image
所以我试图用Java显示一个棋盘。到目前为止,我可以正确绘制一堆矩形并为其着色,并正确调整窗口和矩形的大小。但是,现在我想在这些矩形的顶部添加一个国际象棋棋子的图像,但我不知道如何继续。
我为棋子创建了一个 png 的图像视图,但是当我尝试将其添加到网格窗格中(就像我对矩形所做的那样)时,它给了我一个重复的子错误。
这是迄今为止有效的代码
package test3;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.image.*;
/**
*
*/
public class Test3 extends Application {
GridPane root = new GridPane();
final int size = 8;
ImageView pawn = new ImageView("file:pawn.png");
@Override
public void start(Stage primaryStage) throws Exception {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
Rectangle square = new Rectangle();
Color color;
if ((row + col) % 2 == 0) {
color = Color.CHOCOLATE;
}
else {
color = Color.ANTIQUEWHITE;
}
square.setFill(color);
root.add(square, col, row);
square.widthProperty().bind(root.widthProperty().divide(size));
square.heightProperty().bind(root.heightProperty().divide(size));
}
}
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
创建棋子的图像视图并将其绘制在矩形顶部(就像棋盘上的棋子一样)的最佳方法是什么?我已经有一个文件,比如 pawn.png,我可以制作它的图像视图,但是每当我尝试将图像视图添加到我绘制矩形的网格窗格时,它都会出错。我不知道该怎么办。我尝试使用第二个网格窗格,在其中仅添加图像,但这也会导致重复的子错误。
(我的一些观点可能已经在评论中解决了)
您需要解决的第一件事是为每个方块创建单独的 ImageView 节点,因为您无法复制场景图中的节点。
无论您的正方形是矩形还是 StackPane,都可以解决该问题。
使用矩形:
如果您更喜欢使用矩形,则可以将 ImageView 节点包含在矩形的同一网格位置中,并根据矩形调整 ImageView 节点的宽度/高度。
ImageView pawn = new ImageView(getClass().getResource("pawn.png").toExternalForm());
root.add(pawn, col, row);
pawn.fitWidthProperty().bind(square.widthProperty().subtract(2));
pawn.fitHeightProperty().bind(square.heightProperty().subtract(2));
Run Code Online (Sandbox Code Playgroud)
使用堆栈窗格:
该方法与使用 Rectangle 几乎相同,但您将把 ImageView 节点放置在 StackPane 而不是 GridPane 中。使用 StackPane 的另一个优点是 ImageView 将自动以您的正方形为中心。您还可以包含一个可选代码来调整图像大小以适合正方形。
Background dark = new Background(new BackgroundFill(Color.CHOCOLATE, CornerRadii.EMPTY, Insets.EMPTY));
Background light = new Background(new BackgroundFill(Color.ANTIQUEWHITE, CornerRadii.EMPTY, Insets.EMPTY));
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
ImageView pawn = new ImageView(getClass().getResource("pawn.png").toExternalForm());
StackPane square = new StackPane(pawn);
square.setBackground((row + col) % 2 == 0?dark:light);
root.add(square, col, row);
square.prefWidthProperty().bind(root.widthProperty().divide(size));
square.prefHeightProperty().bind(root.heightProperty().divide(size));
// Comment the below two lines if you don't want the images to resize.
pawn.fitWidthProperty().bind(square.widthProperty().subtract(2));
pawn.fitHeightProperty().bind(square.heightProperty().subtract(2));
}
}
Run Code Online (Sandbox Code Playgroud)
上述两种方法都会产生与下面的 gif 相同的结果。工作演示如下:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ChessBoardDemo extends Application {
GridPane root = new GridPane();
final int size = 8;
@Override
public void start(Stage primaryStage) throws Exception {
yourApproach();
// usingPane();
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.setTitle("ChessBoard");
primaryStage.show();
}
private void usingPane() {
Background dark = new Background(new BackgroundFill(Color.CHOCOLATE, CornerRadii.EMPTY, Insets.EMPTY));
Background light = new Background(new BackgroundFill(Color.ANTIQUEWHITE, CornerRadii.EMPTY, Insets.EMPTY));
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
ImageView pawn = new ImageView(getClass().getResource("pawn.png").toExternalForm());
StackPane square = new StackPane(pawn);
square.setBackground((row + col) % 2 == 0 ? dark : light);
root.add(square, col, row);
square.prefWidthProperty().bind(root.widthProperty().divide(size));
square.prefHeightProperty().bind(root.heightProperty().divide(size));
// Comment the below two lines if you don't want the images to resize.
pawn.fitWidthProperty().bind(square.widthProperty().subtract(2));
pawn.fitHeightProperty().bind(square.heightProperty().subtract(2));
}
}
}
private void yourApproach() {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
Rectangle square = new Rectangle();
square.setFill((row + col) % 2 == 0 ? Color.CHOCOLATE : Color.ANTIQUEWHITE);
root.add(square, col, row);
square.widthProperty().bind(root.widthProperty().divide(size));
square.heightProperty().bind(root.heightProperty().divide(size));
ImageView pawn = new ImageView(getClass().getResource("pawn.png").toExternalForm());
root.add(pawn, col, row);
pawn.fitWidthProperty().bind(square.widthProperty().subtract(2));
pawn.fitHeightProperty().bind(square.heightProperty().subtract(2));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)