我是一名Java初学者,现在正在开展MineSweeper项目。我遇到一个奇怪的问题,当我点击“新建”按钮时我无法正确重置关卡。(虽然它可以在前几次工作)。我认为这可能与Swing EDT有关,但不太确定如何正确修复它。
public class GUI extends JFrame {
private CenterPanel centerPanel;
public GUI() {
super("Minesweeper");
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem newGame = new JMenuItem("New");
centerPanel = new CenterPanel();
menuBar.add(menu);
menu.add(newGame);
newGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
centerPanel.removeAll();
centerPanel.setup();
centerPanel.revalidate();
centerPanel.repaint();
}
});
add(menuBar, BorderLayout.NORTH);
add(centerPanel, BorderLayout.CENTER);
pack();
}
}
public class Board {
private int width;
private int height;
private Square[][] board;
private int mines;
public Board(int x, int y, int z) {
width = x;
height = y;
mines = z;
board = new Square[x][y];
setup();
}
public void setup() {
for (int i = 0; i < mines; i++) {
int randRow = (int) (Math.random() * width);
int randColumn = (int) (Math.random() * height);
while (board[randRow][randColumn] == Square.MINE) {
randRow = (int) (Math.random() * width);
randColumn = (int) (Math.random() * height);
board[randRow][randColumn] = Square.MINE;
}
board[randRow][randColumn] = Square.MINE;
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int neighbourcount = 0;
if (board[i][j] != Square.MINE) {
if (i > 0 && j > 0 && board[i - 1][j - 1] == Square.MINE) {
neighbourcount++;
}
if (i > 0 && board[i - 1][j] == Square.MINE) {
neighbourcount++;
}
if (i > 0 && j < width - 1
&& board[i - 1][j + 1] == Square.MINE) {
neighbourcount++;
}
if (j > 0 && board[i][j - 1] == Square.MINE) {
neighbourcount++;
}
if (i < height - 1 && j > 0
&& board[i + 1][j - 1] == Square.MINE) {
neighbourcount++;
}
if (i < height - 1 && board[i + 1][j] == Square.MINE) {
neighbourcount++;
}
if (i < height - 1 && j < width - 1
&& board[i + 1][j + 1] == Square.MINE) {
neighbourcount++;
}
if (j < width - 1 && board[i][j + 1] == Square.MINE) {
neighbourcount++;
}
board[i][j] = Square.getByNumber(neighbourcount);
}
}
}
}
public Square getSquare(int i, int j) {
return board[i][j];
}
}
public enum Square {
ZERO(0), ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(
8), MINE(9);
private int number;
private Square(int i) {
number = i;
}
public int getNumber() {
return number;
}
public static Square getByNumber(int i) {
for (Square sr : Square.values()) {
if (i == sr.getNumber()) {
return sr;
}
}
return null;
}
}
public class CenterPanel extends JPanel {
private JPanel[][] PanelArray;
private Board board;
public CenterPanel() {
setLayout(new GridLayout(9, 9));
setup();
}
public void setup(){
PanelArray= new JPanel[9][9];
board = new Board(9, 9, 10);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
final int row = i;
final int column = j;
final JButton button = new JButton();
PanelArray[i][j] = new JPanel();
PanelArray[i][j].setLayout(new GridLayout(1,1));
PanelArray[i][j].add(button);
button.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
if (button.getText().equals("")) {
button.setText("F");
} else {
button.setText("");
}
}
if (e.getButton() == MouseEvent.BUTTON1) {
if (button.getText().equals("F")) {
} else {
int k = board.getSquare(row,
column).getNumber();
if (k == 0) {
PanelArray[row][column].remove(button);
revalidate();
repaint();
} else if (k == 9) {
removeAll();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int m = board.getSquare(i, j)
.getNumber();
if (m == 0) {
add(new JLabel(""));
} else if (m == 9) {
add(new JLabel(
" *"));
} else {
add(new JLabel(
" "
+ Integer
.toString(m)));
}
}
}
revalidate();
repaint();
} else {
PanelArray[row][column].remove(button);
PanelArray[row][column].add(new JLabel(" "
+ Integer.toString(k)));
revalidate();
repaint();
}
}
}
}
});
add(PanelArray[i][j]);
}
}
}
}
public class Main {
public static void main(String[] args) {
GUI game = new GUI();
game.setVisible(true);
}
}
感谢您的帮助!
答案 0 :(得分:2)
我本来希望把它作为评论,但是我的解释还不够。
你的电路充满你的电路板是有缺陷的,可以进入无限循环 - &gt;你的应用程序将冻结(你也可能看到你的一个CPU使用率为100%)。
让我们检查一下这个循环:
for (int i = 0; i < mines; i++) {
int randRow = (int) (Math.random() * width);
int randColumn = (int) (Math.random() * height);
while (board[randRow][randColumn] == Square.MINE) {
randRow = (int) (Math.random() * width);
randColumn = (int) (Math.random() * height);
board[randRow][randColumn] = Square.MINE;
}
board[randRow][randColumn] = Square.MINE;
}
在结束时,你打电话:
board[randRow][randColumn] = Square.MINE;
然后while循环将检查条件:board[randRow][randColumn] == Square.MINE
。由于您刚刚将MINE分配给该位置,因此条件始终为真 - &gt;这是你的无限循环。
你应该写一些类似的东西:
Random r = new Random();
for (int i = 0; i < mines; i++) {
int randRow = r.nextInt(width);
int randColumn = r.nextInt(height);
while (board[randRow][randColumn] == Square.MINE) {
randRow = r.nextInt(width);
randColumn = r.nextInt(height);
// Don't do anything here !!!
}
// Now that you found an empty spot, put a mine
board[randRow][randColumn] = Square.MINE;
}