如何扩展 JComponent 并使用它来编写自定义游戏板?
How to extend JComponent and use it to write a customized game board?
我想在 Java 中自学更多有关图形的知识。为此,我正在尝试构建一个国际象棋游戏。我在制作董事会时遇到了第一个障碍。我的想法是,我将有一个名为“Square”的 JComponent 扩展,它是我的容器,用于放置棋盘正方形的颜色和该正方形上的棋子(如果有)。首先,我还没有尝试包括这件作品的任何表现形式,只是方形颜色。稍后我希望有一个抽象的“Pieces”class,它由多个代表所有不同类型的 subclasses 扩展,并根据需要将它们添加到每个 Square。
当我执行以下命令时,我只在左上角看到一个黑色方块。
ChessBoardTest.java
public class ChessBoardTest {
public static void main(String[] args) {
ChessBoard Board = new ChessBoard();
Board.Display();
}
}
ChessBoard.java
public class ChessBoard extends JFrame {
public static final int FRAME_WIDTH = 500;
public static final int FRAME_HEIGHT = 500;
// Declare instance variables
private Square[][] square = new Square[rows][cols];
private final static int rows = 8;
private final static int cols = 8;
public ChessBoard() {
}
public void Display() {
JPanel Board_Layout = new JPanel();
Board_Layout.setLayout(new GridLayout(8,8));
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
if((i+j) % 2 == 0) {
square[i][j] = new Square(1);
Board_Layout.add(square[i][j]);
} else {
square[i][j] = new Square(0);
Board_Layout.add(square[i][j]);
}
}
}
setTitle("Chess Mod");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(Board_Layout);
setVisible(true);
}
public void messageBox(String pMessage) {
JOptionPane.showMessageDialog(this, pMessage, "Message", JOptionPane.PLAIN_MESSAGE);
}
}
Square.java
public class Square extends JComponent {
private int color;
public Square(int c) {
this.color=c;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.color == 1) {
g.setColor(new Color(0,0,0));
} else {
g.setColor(new Color(255,255,255));
}
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
}
}
I only get one black square in the upper left hand corner.
主要是因为下面的调用:
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
getX()
returns 被调用的 Component
的水平像素 offset/location,相对于包含 [=13] 的 Container
=]. getY()
因此 returns 相对于包含 Component
的 Container
调用的 Component
的垂直像素 offset/location。 =43=]
getWidth()
和 getHeight()
return Component
.
的大小
所以假设 Component
位于索引 2 的行和索引 3 的列,其坐标大约在 x == 3 * w / 8
和 y == 2 * h / 8
,其中 w
和 h
是父级 Container
(即 Board_Layout
面板)的大小(分别为宽度和高度)。假设当您显示图形用户界面时 Board_Layout
的大小为 300x300...这意味着我提到的位置处的 Square
只会绘制从 x == 112
开始的区域和 y == 75
并扩展为 Board_Layout
宽度(和高度)的八分之一(因为网格中有 8 行和 8 列)。但是 Square
本身的大小也是 Board_Layout
宽度(和高度)的八分之一,即大约 37x37。因此,从位置 112,75 开始并扩展的绘制区域根本不会显示(因为它完全位于 Square
的大小之外)。
只有左上角 Square
会有一些绘画,因为它在父级中的边界恰好与绘制区域相交。
要解决此问题,Graphics
对象的位置应相对于每个 Square
而不是其父对象 Board_Layout
。例如:
g.fillRect(0, 0, getWidth(), getHeight());
我想在 Java 中自学更多有关图形的知识。为此,我正在尝试构建一个国际象棋游戏。我在制作董事会时遇到了第一个障碍。我的想法是,我将有一个名为“Square”的 JComponent 扩展,它是我的容器,用于放置棋盘正方形的颜色和该正方形上的棋子(如果有)。首先,我还没有尝试包括这件作品的任何表现形式,只是方形颜色。稍后我希望有一个抽象的“Pieces”class,它由多个代表所有不同类型的 subclasses 扩展,并根据需要将它们添加到每个 Square。
当我执行以下命令时,我只在左上角看到一个黑色方块。
ChessBoardTest.java
public class ChessBoardTest {
public static void main(String[] args) {
ChessBoard Board = new ChessBoard();
Board.Display();
}
}
ChessBoard.java
public class ChessBoard extends JFrame {
public static final int FRAME_WIDTH = 500;
public static final int FRAME_HEIGHT = 500;
// Declare instance variables
private Square[][] square = new Square[rows][cols];
private final static int rows = 8;
private final static int cols = 8;
public ChessBoard() {
}
public void Display() {
JPanel Board_Layout = new JPanel();
Board_Layout.setLayout(new GridLayout(8,8));
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
if((i+j) % 2 == 0) {
square[i][j] = new Square(1);
Board_Layout.add(square[i][j]);
} else {
square[i][j] = new Square(0);
Board_Layout.add(square[i][j]);
}
}
}
setTitle("Chess Mod");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(Board_Layout);
setVisible(true);
}
public void messageBox(String pMessage) {
JOptionPane.showMessageDialog(this, pMessage, "Message", JOptionPane.PLAIN_MESSAGE);
}
}
Square.java
public class Square extends JComponent {
private int color;
public Square(int c) {
this.color=c;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.color == 1) {
g.setColor(new Color(0,0,0));
} else {
g.setColor(new Color(255,255,255));
}
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
}
}
I only get one black square in the upper left hand corner.
主要是因为下面的调用:
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
getX()
returns 被调用的 Component
的水平像素 offset/location,相对于包含 [=13] 的 Container
=]. getY()
因此 returns 相对于包含 Component
的 Container
调用的 Component
的垂直像素 offset/location。 =43=]
getWidth()
和 getHeight()
return Component
.
所以假设 Component
位于索引 2 的行和索引 3 的列,其坐标大约在 x == 3 * w / 8
和 y == 2 * h / 8
,其中 w
和 h
是父级 Container
(即 Board_Layout
面板)的大小(分别为宽度和高度)。假设当您显示图形用户界面时 Board_Layout
的大小为 300x300...这意味着我提到的位置处的 Square
只会绘制从 x == 112
开始的区域和 y == 75
并扩展为 Board_Layout
宽度(和高度)的八分之一(因为网格中有 8 行和 8 列)。但是 Square
本身的大小也是 Board_Layout
宽度(和高度)的八分之一,即大约 37x37。因此,从位置 112,75 开始并扩展的绘制区域根本不会显示(因为它完全位于 Square
的大小之外)。
只有左上角 Square
会有一些绘画,因为它在父级中的边界恰好与绘制区域相交。
要解决此问题,Graphics
对象的位置应相对于每个 Square
而不是其父对象 Board_Layout
。例如:
g.fillRect(0, 0, getWidth(), getHeight());