初始化后 JButtons 未显示 [Java Swing]
JButtons not showing up after initialisation [Java Swing]
我知道这里有很多关于堆栈溢出的问题,关于 JElements 没有出现,都是因为有人忘记在构造函数的末尾添加 setVisible(true)
。但至少我相信我的问题有所不同。我目前正在为大学制作国际象棋游戏,为此我有
- 游戏class:一切都在这里
- 抽象 Piece class 扩展包 Pieces 中的 JButton
- 和每个 Piece(Rook,Bishop,...)的 class 每个扩展 Piece 并位于 Pieces 包中
在我写更多之前又是一个愚蠢的错误,这里是代码:
import javax.swing.*;
import Pieces.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Game extends JFrame {
private static final int width = 8;
private static final int height = 8;
private static Piece clicked;
private static Piece[][] fields = new Piece[width][height];
private JPanel main = new JPanel();
public static void init(JPanel g) {
for (int y = 0; y < fields.length; y++) {
for (int x = 0; x < fields[y].length; x++) {
if (y == 1) fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
else if (y == 6) fields[y][x] = new Pawn(x, y, false);
else {
fields[y][x] = new Empty(x,y,true);
}
fields[y][x].addActionListener(e -> {
var p = (Piece) e.getSource();
System.out.println(p.getX() + p.getY());
});
g.add(fields[y][x]);
}
}
}
public Game() {
main.setBackground(Color.blue.darker());
main.setLayout(new GridLayout(8,8));
this.setSize(800,800);
init(main);
this.add(main);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
var g = new Game();
}
}
package Pieces;
import javax.swing.*;
public abstract class Piece extends JButton {
private int x;
private int y;
private final boolean isWhite;
public Piece(int x, int y, boolean isWhite) {
this.x = x;
this.y = y;
this.isWhite = isWhite;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
每个 Piece 扩展 class 的设置完全像这样:
package Pieces;
import java.awt.*;
public class Pawn extends Piece{
public Pawn(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText(isWhite ? "Pawn" : "pawn");
}
}
预期行为:
- 打开一个window,里面有64个JButtons,显示它们所代表的Piece的名称(确实有一个Empty-class用于未使用的字段)
实际行为:
打开 window,左上角有一个按钮,但首先当我用光标浏览字段时,按钮开始出现
状态 1:state 1
状态 2:state 2
您不能像这样覆盖 getX
和 getY
,布局管理器使用这些属性来布局组件。
相反,可以使用 Point
来存储虚拟或“单元格”位置
public static abstract class Piece extends JButton {
private final boolean isWhite;
private Point cell;
public Piece(int x, int y, boolean isWhite) {
cell = new Point(x, y);
this.isWhite = isWhite;
}
public Point getCell() {
return cell;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
可运行示例...
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.GridLayout;
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new BoardPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BoardPane extends JPanel {
private static final int width = 8;
private static final int height = 8;
private Piece clicked;
private Piece[][] fields = new Piece[width][height];
public BoardPane() {
setBackground(Color.blue.darker());
setLayout(new GridLayout(8, 8));
buildBoard();
}
protected void buildBoard() {
for (int y = 0; y < fields.length; y++) {
for (int x = 0; x < fields[y].length; x++) {
if (y == 1) {
fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
} else if (y == 6) {
fields[y][x] = new Pawn(x, y, false);
} else {
fields[y][x] = new Empty(x,y,true);
}
fields[y][x].addActionListener(e -> {
var p = (Piece) e.getSource();
System.out.println(p.getCell());
});
add(fields[y][x]);
}
}
}
}
public static abstract class Piece extends JButton {
private final boolean isWhite;
private Point cell;
public Piece(int x, int y, boolean isWhite) {
cell = new Point(x, y);
this.isWhite = isWhite;
}
public Point getCell() {
return cell;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
public static class Pawn extends Piece {
public Pawn(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText(isWhite ? "Pawn" : "pawn");
}
}
public static class Empty extends Piece {
public Empty(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText("X");
}
}
}
我知道这里有很多关于堆栈溢出的问题,关于 JElements 没有出现,都是因为有人忘记在构造函数的末尾添加 setVisible(true)
。但至少我相信我的问题有所不同。我目前正在为大学制作国际象棋游戏,为此我有
- 游戏class:一切都在这里
- 抽象 Piece class 扩展包 Pieces 中的 JButton
- 和每个 Piece(Rook,Bishop,...)的 class 每个扩展 Piece 并位于 Pieces 包中
在我写更多之前又是一个愚蠢的错误,这里是代码:
import javax.swing.*;
import Pieces.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Game extends JFrame {
private static final int width = 8;
private static final int height = 8;
private static Piece clicked;
private static Piece[][] fields = new Piece[width][height];
private JPanel main = new JPanel();
public static void init(JPanel g) {
for (int y = 0; y < fields.length; y++) {
for (int x = 0; x < fields[y].length; x++) {
if (y == 1) fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
else if (y == 6) fields[y][x] = new Pawn(x, y, false);
else {
fields[y][x] = new Empty(x,y,true);
}
fields[y][x].addActionListener(e -> {
var p = (Piece) e.getSource();
System.out.println(p.getX() + p.getY());
});
g.add(fields[y][x]);
}
}
}
public Game() {
main.setBackground(Color.blue.darker());
main.setLayout(new GridLayout(8,8));
this.setSize(800,800);
init(main);
this.add(main);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
var g = new Game();
}
}
package Pieces;
import javax.swing.*;
public abstract class Piece extends JButton {
private int x;
private int y;
private final boolean isWhite;
public Piece(int x, int y, boolean isWhite) {
this.x = x;
this.y = y;
this.isWhite = isWhite;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
每个 Piece 扩展 class 的设置完全像这样:
package Pieces;
import java.awt.*;
public class Pawn extends Piece{
public Pawn(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText(isWhite ? "Pawn" : "pawn");
}
}
预期行为:
- 打开一个window,里面有64个JButtons,显示它们所代表的Piece的名称(确实有一个Empty-class用于未使用的字段)
实际行为:
打开 window,左上角有一个按钮,但首先当我用光标浏览字段时,按钮开始出现
状态 1:state 1
状态 2:state 2
您不能像这样覆盖 getX
和 getY
,布局管理器使用这些属性来布局组件。
相反,可以使用 Point
来存储虚拟或“单元格”位置
public static abstract class Piece extends JButton {
private final boolean isWhite;
private Point cell;
public Piece(int x, int y, boolean isWhite) {
cell = new Point(x, y);
this.isWhite = isWhite;
}
public Point getCell() {
return cell;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
可运行示例...
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.GridLayout;
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new BoardPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BoardPane extends JPanel {
private static final int width = 8;
private static final int height = 8;
private Piece clicked;
private Piece[][] fields = new Piece[width][height];
public BoardPane() {
setBackground(Color.blue.darker());
setLayout(new GridLayout(8, 8));
buildBoard();
}
protected void buildBoard() {
for (int y = 0; y < fields.length; y++) {
for (int x = 0; x < fields[y].length; x++) {
if (y == 1) {
fields[y][x] = new Pawn(x, y, true); //2nd or 7th row is filled with pawns
} else if (y == 6) {
fields[y][x] = new Pawn(x, y, false);
} else {
fields[y][x] = new Empty(x,y,true);
}
fields[y][x].addActionListener(e -> {
var p = (Piece) e.getSource();
System.out.println(p.getCell());
});
add(fields[y][x]);
}
}
}
}
public static abstract class Piece extends JButton {
private final boolean isWhite;
private Point cell;
public Piece(int x, int y, boolean isWhite) {
cell = new Point(x, y);
this.isWhite = isWhite;
}
public Point getCell() {
return cell;
}
public boolean isWhite() {
return isWhite;
}
public boolean canMoveTo(int toX, int toY) {
return true;
}
}
public static class Pawn extends Piece {
public Pawn(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText(isWhite ? "Pawn" : "pawn");
}
}
public static class Empty extends Piece {
public Empty(int x, int y, boolean isWhite) {
super(x, y, isWhite);
this.setText("X");
}
}
}