gpt4 book ai didi

java - 单击“确定”按钮后再次出现消息对话框

转载 作者:行者123 更新时间:2023-12-01 16:08:44 26 4
gpt4 key购买 nike

在之前得到良好的帮助后,我已经完成了我的扫雷游戏。然而,有一个问题我想不通。游戏本身运行良好,但是,我可以选择让用户更改难度设置(初级、中级、高级),这让我感到悲伤。用户从 JMenuBar 中选择“游戏”,然后从下拉菜单中选择“更改难度”。这会调用 selectDifficulty() 方法,该方法会打开一个 JOptionMessageBox,该 JOptionMessageBox 使用 JRadioButtons 让用户选择 4 个选项之一(第 4 个选项是自定义选项 - 但到目前为止我还没有实现)。当用户第一次更改难度模式时,该对话框似乎工作正常。然而,当用户第二次或更多次尝试改变难度时,游戏会执行该设置,然后再次出现对话框并提示用户重新选择难度。有时这种情况会重复两次,然后消失,有时会重复 4 或 5 次。我将不胜感激任何帮助,因为我不知道为什么会发生这种情况。

此外,我也希望获得一些关于如何改进难度设置更改的建议。按照目前的情况,代码删除了 JPanel 和雷区(由按钮组成),并使用新的难度设置重新实例化按钮/Japanels。有没有办法提高效率?

有一个逻辑类和一个 GUI 玻璃。上述两个问题都存在于 GUI 类中。

private void selectDifficulty() {

group.add(b1);
group.add(b2);
group.add(b3);
group.add(b4);
b1.setSelected(true);

Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
JOptionPane.showMessageDialog(null, array);

if (b1.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 1;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 1;
}else {
rw = 20;
rh = 20;
mode = 1;
}
start(9,9);

}else if (b2.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 2;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 2;
}else {
rw = 20;
rh = 20;
mode = 2;
}
start(15,15);
}else if (b3.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 3;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 3;
}else {
rw = 20;
rh = 20;
mode = 3;
}
start(20,20);
}
}

完整代码:图形用户界面类

import java.awt.* ;
import java.awt.event.* ;
import javax.swing.* ;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;


public class MineSweeperGUI extends JFrame implements MouseListener {

MinesweeperLogic logicClass = new MinesweeperLogic();
JButton newGameButton = new JButton ("New Game");
JMenuItem optionsButton = new JMenuItem ("Change Difficulty");
JRadioButton b1 = new JRadioButton ("Beginner: 9 X 9 Grid (10 Mines)");
JRadioButton b2 = new JRadioButton ("Intermediate: 15 X 15 Grid (36 Mines)");
JRadioButton b3 = new JRadioButton ("Advanced: 20 X 20 Grid (80 Mines)");
JRadioButton b4 = new JRadioButton ("Custom");
ButtonGroup group = new ButtonGroup();
JMenuItem aboutButton = new JMenuItem ("About Minesweeper");
JPanel p = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
int w, h, rw = 0, rh = 0, mode = 1;


public void MineSweeper(int width, int height) {
//setupI();
w = width;
h = height;
logicClass.startNewGame(w, h);
GridLayout layout = new GridLayout (w, h);
p2.setLayout(new BorderLayout());
p.setLayout(layout);
p2.add(p, BorderLayout.CENTER);
for(int x = 0 ; x < w ; x++) {
for(int y = 0 ; y < h ; y++) {
logicClass.label[x][y] = new Button();
logicClass.label[x][y].setPreferredSize(new Dimension(20,20));
logicClass.label[x][y].setBackground(new Color(33,58,156));
logicClass.label[x][y].addMouseListener (this);
p.add(logicClass.label[x][y]);
}
}
JMenuBar mb = new JMenuBar();
JMenu m = new JMenu("Game");
JMenu m2 = new JMenu("Help");
m.add(optionsButton);
m2.add(aboutButton);
mb.add(m);
mb.add(m2);

p2.add(p3, BorderLayout.PAGE_START);
newGameButton.setPreferredSize (new Dimension(87, 20));
newGameButton.setFont(new Font("sansserif",Font.BOLD,11));
newGameButton.setForeground(Color.black);
newGameButton.setBackground(new Color(235,52,52));
Border thickBorder = new LineBorder(Color.black, 2);
newGameButton.setBorder(thickBorder);


p3.add(newGameButton);
newGameButton.addMouseListener(this);

optionsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
selectDifficulty();
}
});

this.setJMenuBar(mb);
this.add(p2);
this.pack();
this.setVisible(true);

}


private void start(int width, int height){
p2.remove(p);
for(int x = 0 ; x < rw ; x++) {
for(int y = 0 ; y < rh ; y++) {
p.remove(logicClass.label[x][y]);
}
}
p2.remove(p3);
p3.remove(newGameButton);
this.remove(p2);
MineSweeper(width, height);
}

private void lose() {
JOptionPane.showMessageDialog(this, "GAME OVER - YOU LOSE! Starting New Game", "Game Over", JOptionPane.INFORMATION_MESSAGE);
newGame();
}

private void win() {
JOptionPane.showMessageDialog(this, "YOU WIN! Starting New Game", "CONGRATULATIONS", JOptionPane.INFORMATION_MESSAGE);
newGame();
}


private void newGame() {
if(mode==1){
rw = 9;
rh = 9;
start(9,9);
}else if(mode==2){
rw = 15;
rh = 15;
start(15,15);
}else{
rw = 20;
rh = 20;
start(20,20);
}
}


public void mouseClicked(MouseEvent e) {
if(e.getSource() == newGameButton) {
if(e.getButton() == e.BUTTON1) {
newGame();
}
}

for (int x = 0 ; x < w; x++) {
for (int y = 0 ; y < h; y++) {
if(e.getSource() == logicClass.label[x][y]) {
if(e.getButton() == e.BUTTON1) {
if(logicClass.openCell(x, y) == false) {
lose();
} else {
for (int q = 0; q < w; q++) {
for (int j = 0; j < h; j++) {
if (logicClass.label[q][j].getBackground()==Color.green) {
win();
}
}
}
}
}else if(e.getButton() == e.BUTTON3) {
logicClass.markCell(x, y);
}
}
}
}
}

private void selectDifficulty() {

group.add(b1);
group.add(b2);
group.add(b3);
group.add(b4);
b1.setSelected(true);

Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
JOptionPane.showMessageDialog(null, array);

if (b1.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 1;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 1;
}else {
rw = 20;
rh = 20;
mode = 1;
}
start(9,9);

}else if (b2.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 2;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 2;
}else {
rw = 20;
rh = 20;
mode = 2;
}
start(15,15);
}else if (b3.isSelected()) {
if (mode == 1){
rw = 9;
rh = 9;
mode = 3;
}else if(mode == 2){
rw = 15;
rh = 15;
mode = 3;
}else {
rw = 20;
rh = 20;
mode = 3;
}
start(20,20);
}
}

public static void main(String[]args) {
MineSweeperGUI guiClass = new MineSweeperGUI();
guiClass.MineSweeper(9,9);
}

public void mouseEntered(MouseEvent e) {}

public void mousePressed(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}
}

逻辑类: 导入 java.awt.* ;

public class MinesweeperLogic {

public int width, height;
private int w, h, maxBombs;
private boolean mine[][];
private boolean flag[][];
private boolean isClicked[][];
private boolean isZero[][];
private boolean marked;
MineSweeperGUI guiClass;
Button[][] label;
private int surBombs;
private String temp;
private double mineRatio;


public void startNewGame(int width, int height) {
w = width;
h = height;
label = new Button[w][h];
mine = new boolean[w][h];
flag = new boolean[w][h];
isClicked = new boolean[w][h];
isZero = new boolean[w][h];
if ( (w*h) <= 81) {
mineRatio = 0.13;
}else if ( (w*h) <= 255) {
mineRatio = 0.16;
}else {
mineRatio = 0.2;
}
maxBombs = (int) Math.floor (w * h * mineRatio);
for (int i = 0; i < maxBombs; i++) {
int x = (int) (Math.random() * w);
int y = (int) (Math.random() * h);
if (mine[x][y] == false) {
mine[x][y] = true;
isClicked[x][y] = false;
flag[x][y] = false;
isZero[x][y] = false;
} else {
i--;
}
}
}


int getWidth() {
return w;
}


int getHeight() {
return h;
}


boolean openCell(int x, int y) {
isClicked[x][y] = true;
if (mine[x][y] == true && flag[x][y] == false) {
lose();
return false;
} else if (getValue(x, y) > 0 && flag[x][y] == false) {
temp = Integer.toString (getValue(x, y));
label[x][y].setLabel (temp);
label[x][y].setBackground (new Color (111,184,252));
checkWin();
return true;
} else if (getValue(x, y) == 0 && flag[x][y] == false) {
for (int q = x-1; q <= x+1; q++) {
if(q < 0 || q >= w) {
continue;
}
for (int i = y-1; i <= y+1; i++) {
if(i < 0 || i >= h || flag[q][i] == true) { // makes sure that it wont have an error for buttons next to the wall
continue;
}
label[q][i].setBackground(new Color (111,184,252));
if (getValue(q, i) != 0) { // opens surrounding cells that have mines around them (max 8 cells)
temp = Integer.toString (getValue(q, i));
label[q][i].setLabel (temp);
isClicked[q][i] = true;
} else {
for (int k = x-1; k <= x+1; k++) {
if(k < 0 || k >= w) {
continue;
}
for (int m = y-1; m <= y+1; m++) {
if (m < 0 || m >= h || flag[k][m] == true) { // makes sure that it wont have an error for buttons next to the wall
continue;
}
if (isClicked[k][m] == false && getValue(k, m) == 0) { // recursively continues to open all surrounding cells with no mines around them
openCell(k, m);
}
}
}
}
}
}
checkWin();
return true;
} else {
return true;
}
}


boolean markCell(int x, int y) {
if (flag[x][y] == true) {
flag[x][y] = false;
label[x][y].setLabel ("");
label[x][y].setForeground (Color.black);
label[x][y].setFont (new Font (null, Font.PLAIN, 12));
return false;
}
if (isClicked[x][y] == false && flag[x][y] == false) {
flag[x][y] = true;
label[x][y].setFont (new Font ("sansserif", Font.BOLD, 14));
label[x][y].setLabel ("<|");
label[x][y].setForeground (Color.red);
}
if (mine[x][y] == true) {
return true;
} else {
return false;
}
}


boolean isOpen(int x, int y) {
if (isClicked[x][y] == false) {
return false;
} else {
return true;
}
}


boolean isMarked(int x, int y) {
if (flag[x][y] == true) {
return true;
} else {
return false;
}
}


int getValue(int x, int y) {
if (mine[x][y] == true) {
return -1;
} else {
return neighborBombs(x, y);
}
}


private int neighborBombs(int x, int y) { // checks surrounding 8 squares for number of bombs (it does include itself, but has already been checked for a bomb so it won't matter)
surBombs = 0;
for (int q = x-1; q <= x+1; q++) {
if (q < 0 || q >= w) {
continue;
}
for (int i = y-1; i <= y+1; i++) {
if (i < 0 || i >= h) { // makes sure that it wont have an error for buttons next to the wall
continue;
}
if (mine[q][i] == true) {
surBombs++;
}
}
}
return surBombs;
}


private void lose() {
for (int q = 0; q < w; q++) {
for (int j = 0; j < h; j++) {
if (mine[q][j] == true) {
if (label[q][j].getLabel().equals ("<|")) {
label[q][j].setBackground (Color.green);
} else {
label[q][j].setBackground (Color.red);
label[q][j].setLabel ("*");
label[q][j].setForeground (Color.black);
}


}
}
}
}


private void checkWin() {
int count = 0;
int count2 = 0;
for (int i = 0; i < w; i++){
for (int j = 0; j < h; j++) {
if (isClicked[i][j] == true){
count++;
}
if (mine[i][j] == true){
count2++;
}
}
}
if ( (count + count2) == (w * h) ){
win();
}
}


private void win() {
for (int q = 0; q < w; q++) {
for (int j = 0; j < h; j++) {
if (mine[q][j] == true) {
label[q][j].setBackground (Color.green);
label[q][j].setForeground (Color.red);
label[q][j].setFont (new Font ("sansserif", Font.BOLD, 14));
label[q][j].setLabel ("<|");
}
}
}
}
}

最佳答案

您在 start 的末尾调用 MineSweeper(width, height) (应该是小写,因为它是一个方法),您在 selectDifficulty< 中调用它.

MineSweeper 会创建新的所有组件。 optionsButton 不是新创建的,因此您向其添加另一个 ActionListener。当您按下按钮时,每个 ActionListener 都会被调用,因此 selectDifficulty 被调用的次数越来越多。

最简单的解决方法是将此 ActionListener 添加到 MineSweeperGUI 的构造函数中,但您应该重构源代码,尽可能只创建一次所有组件。至少整个菜单应该转到构造函数。

关于java - 单击“确定”按钮后再次出现消息对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2005757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com