当前位置: 首页 > 知识库问答 >
问题:

如何在带有图像的矩形网格窗格上绘制?(JavaFX)

薛承志
2023-03-14

所以我试图用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);
    }

}

创建象棋棋子的图像视图并将其绘制在矩形之上的最佳方法是什么,就像棋子在棋盘上的样子一样?我已经有了一个文件,比如说pawn.png,我可以对其进行图像视图,但是每当我尝试将图像视图添加到我绘制矩形的网格中时,都会出现错误。我不知道该怎么办。我尝试过在第二个网格中只添加图像,但这也会出现重复的子错误。

共有1个答案

俞飞鸣
2023-03-14

(我的一些观点可能已经在评论中提到了)

您需要解决的第一件事是为每个正方形创建单独的ImageView节点,因为您不能在scenegraph中复制节点。

无论矩形或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));

使用StackPane:

该方法与使用 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));
    }
}

以上两种方法中的任何一种都会产生与以下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);
    }
}
 类似资料:
  • 我是JavaFx的新手,我想知道如何绘制网格,我想在网格角上绘制点。我应该使用网格窗格作为基础还是线条图?使用网格并在其上绘制的最佳类是什么?

  • 实际上,我可以使用函数来完成。我从“HTML5画布-如何在图像背景上画一条线?”中得到的东西。但是我需要在不使用from函数的情况下绘制图像,如下所示:

  • 问题内容: 我有一张根据某些数据计算得出的图表,绘制在matplotlib中。我想在此图的全局最大值周围绘制一个矩形区域。我试过,但通话时似乎没有出现矩形 那么,如何在matplotlib图上绘制矩形区域?谢谢! 问题答案: 最可能的原因是在调用axhspan时将数据单元用作x参数。从函数的文档(我的重点): y坐标以数据单位为单位, x坐标以轴(相对于0-1)为单位 。 因此,任何向左拉伸为0或

  • 我想这可能是图像后的行和列的问题,但是我已经尝试了一些方法,但没有成功。非常感谢任何帮助。谢谢

  • DrawImage类进行实际绘制

  • 我似乎在绘制正确的十六进制网格时遇到了一点麻烦: 正如您所看到的,六边形只是稍微不对齐,尽管我相信我的数学是正确的(其中一些可以通过http://www.redblobgames.com/grids/hexagons/进行验证)。 我的绘制方法是从左上六边形(第一行的第一个瓷砖)开始,绘制那一行瓷砖。然后对于下一行,有一个负X偏移量和正Y偏移量等,直到它到达中间行,在中间行X偏移量增加,直到0: