【问题标题】:How to reset Minesweeper game board in Java.Swing如何在 Java.Swing 中重置扫雷游戏板
【发布时间】:2014-12-25 04:36:11
【问题描述】:

我一直试图让我的代码在用滑块点击确定按钮后重置,但是,我没有这样的运气。有没有人知道如何将其合并到我的代码中?

附:重置必须在类字段中。

package GUI;

import java.awt.GridLayout;
import javax.swing.JPanel;

public class GameDisplay extends JPanel {
    private static final long serialVersionUID = 1L;
    private boolean activated;

    public GameDisplay(Model.Field field) {
        setLayout(new GridLayout(GUI.SizeDialog.currentRows, GUI.SizeDialog.currentColumns));
        for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
            for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
               add(field.Cells[i][j]);   
            }
        }
    }

    public boolean isActive() {
        return activated;
    }

    public void setActive(boolean activated) {
        this.activated = activated;
    }
}

Field

package Model;

import java.awt.Dimension;
import java.util.ArrayList;

import GUI.SizeDialog;

public class Field {
    private int difficultyFactor;
    public static final int EASY = 1;
    public static final int NORMAL = 2;
    public static final int HARD = 3;
    public  Cell[][] Cells;

    public Field() {
        Cells = new Cell[GUI.SizeDialog.currentRows][GUI.SizeDialog.currentColumns];
        for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
            for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
                Cells[i][j]= new Cell();

            }
        }

    }
    public void reset(){
        Cells = new Cell[GUI.SizeDialog.currentRows][GUI.SizeDialog.currentColumns];
        for (int i = 0; i < GUI.SizeDialog.currentRows; ++i) {
            for (int j = 0; j < GUI.SizeDialog.currentColumns; ++j) {
                Cells[i][j]= new Cell();
            }
        }
    }

    public void setDifficultyFactor(int level) {
        switch (level) {
        case EASY:
            difficultyFactor = EASY;
            break;
        case NORMAL:
            difficultyFactor = NORMAL;
            break;
        case HARD:
            difficultyFactor = HARD;
            break;
        default:
            difficultyFactor = NORMAL;
        }
    }
}

SizeDialog

package GUI;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Hashtable;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import Model.Field;


public class SizeDialog extends JDialog {

    private static final long serialVersionUID = 1L;
    private Model.Field field;
    private GUI.GameDisplay GameDisplay;
    public static Integer currentRows = 4;
    public static Integer currentColumns = 4;

    public SizeDialog() {
        JPanel dialogBoxPanel = new JPanel();
        BorderLayout dialogLayout = new BorderLayout();
        dialogBoxPanel.setLayout(dialogLayout);

        JSlider rowCount = new JSlider(4, 10, 4);
        JSlider columnCount = new JSlider(4, 10, 4);

        Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
        labelTable.put(new Integer(4), new JLabel("4"));
        labelTable.put(new Integer(10), new JLabel("10"));

        rowCount.setLabelTable(labelTable);
        rowCount.setPaintLabels(true);

        columnCount.setLabelTable(labelTable);
        columnCount.setPaintLabels(true);

        JLabel row = new JLabel();
        JLabel column = new JLabel();

        JPanel rowPanel = new JPanel();
        JPanel columnPanel = new JPanel();

        JLabel rowPosition = new JLabel();
        rowPosition.setText("Rows: 4");

        JLabel columnPosition = new JLabel();
        columnPosition.setText("Columns: 4");

        rowCount.addChangeListener(getCurrentRows(rowCount, "row", rowPosition));
        columnCount.addChangeListener(getCurrentColumns(columnCount, "column", columnPosition));

        JButton okButton = new JButton("OK");
        okButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                field.reset();
                SizeDialog.this.dispose();

            }

        });
        rowPanel.add(rowPosition, BorderLayout.WEST);
        rowPanel.add(row, BorderLayout.CENTER);
        rowPanel.add(rowCount, BorderLayout.EAST);
        columnPanel.add(columnPosition, BorderLayout.WEST);
        columnPanel.add(column, BorderLayout.CENTER);
        columnPanel.add(columnCount, BorderLayout.EAST);

        dialogBoxPanel.add(rowPanel, BorderLayout.NORTH);
        dialogBoxPanel.add(columnPanel, BorderLayout.CENTER);
        dialogBoxPanel.add(okButton, BorderLayout.SOUTH);

        setContentPane(dialogBoxPanel);
        setMinimumSize(new Dimension(300, 150));
        setLocationRelativeTo(null);
    }



     private ChangeListener getCurrentColumns(final JSlider columnCount, final String string, final JLabel columnPosition) {
         ChangeListener changeListener = new ChangeListener() {
              public void stateChanged(ChangeEvent changeEvent) {
                JSlider theSlider = (JSlider) changeEvent.getSource();
                if (!theSlider.getValueIsAdjusting()) {
                    int sliderValue = theSlider.getValue();
                    columnPosition.setText("columns:" + sliderValue);    
                    SizeDialog.currentColumns = sliderValue;
                }
              }
         };
         return changeListener;
     }




    private ChangeListener getCurrentRows(final JSlider rowCount, final String string, final JLabel rowPosition) {
         ChangeListener changeListener = new ChangeListener() {
              public void stateChanged(ChangeEvent changeEvent) {
                JSlider theSlider = (JSlider) changeEvent.getSource();
                if (!theSlider.getValueIsAdjusting()) {
                    int sliderValue = theSlider.getValue();
                    rowPosition.setText("Rows:" + sliderValue);  
                    SizeDialog.currentRows = sliderValue;
                    }
                }
              };

        return changeListener;
      }
}

MainFrame

package GUI;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class MainFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    private static JPanel centerPanel;
    public static final String EASY = "Easy";
    public static final String NORMAL = "Normal";
    public static final String HARD = "Hard";

    public MainFrame(JPanel centerPanel) {
        // Setup of Main
        super("The True/False Game");
        this.centerPanel = centerPanel;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setup();
    }

    private void setup() {
        // Setup of centerPanel
        add(centerPanel);
        pack();
    }

    public JMenuBar setUpMenuBar(ActionListener listener) {
        // create the necessary menu items and menus
        JMenuBar menuBar = new JMenuBar();

        JMenu settingsMenu = new JMenu("Settings");
        JMenuItem size = new JMenuItem("Size");

        size.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object valueBox = new SizeDialog();
                ((Window) valueBox).setVisible(true);
            }
        });

        JMenu difficultyMenu = new JMenu("Difficulty Level");
        ButtonGroup levelGroup = new ButtonGroup();
        JCheckBoxMenuItem easyDifficultyItem = new JCheckBoxMenuItem(EASY);
        JCheckBoxMenuItem normalDifficultyItem = new JCheckBoxMenuItem(NORMAL);
        JCheckBoxMenuItem hardDifficultyItem = new JCheckBoxMenuItem(HARD);

        easyDifficultyItem.setSelected(true); // Default difficulty setting

        // this button group ensures that only one check box is selected
        levelGroup.add(easyDifficultyItem);
        levelGroup.add(normalDifficultyItem);
        levelGroup.add(hardDifficultyItem);

        difficultyMenu.add(easyDifficultyItem);
        difficultyMenu.add(normalDifficultyItem);
        difficultyMenu.add(hardDifficultyItem);

        settingsMenu.add(size);
        settingsMenu.add(difficultyMenu);
        menuBar.add(settingsMenu);

        // use a single listener to handle all menu item selections
        for (int i = 0; i < menuBar.getMenuCount(); ++i) {
            for (JMenuItem item : getMenuItems(menuBar.getMenu(i))) {
                item.addActionListener(listener);
            }
        }

        return menuBar;

    }

    // this recursion works because JMenu is a subclass of JMenuItem!
    private static List<JMenuItem> getMenuItems(JMenuItem item) {
        List<JMenuItem> items = new ArrayList<>();

        if (item instanceof JMenu) {
            JMenu menu = (JMenu) item;
            for (int i = 0; i < menu.getItemCount(); ++i) {
                items.addAll(getMenuItems(menu.getItem(i)));
            }
        } else {
            items.add(item);
        }

        return items;
    }

}

App

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JMenuBar;

import Model.Cell;
import Model.Field;
import GUI.MainFrame;
import GUI.SizeDialog;

public class App {
    // Main Objects
    private static GUI.MainFrame MainFrame;
    private static GUI.GameDisplay GameDisplay;
    private static Model.Field field;
    public static GUI.SizeDialog SizeDialog;


    public static void main(String[] args) {
        // Setup of the Main Objects
        field = new Model.Field();
        GameDisplay = new GUI.GameDisplay(field);
        MainFrame = new MainFrame(GameDisplay);
        MainFrame.setMinimumSize(new Dimension(500, 500));

        MainFrame.getContentPane().add(GameDisplay);
        // Setup of the Menu Bar
        JMenuBar menuBar = MainFrame.setUpMenuBar(menuListener);
        MainFrame.setJMenuBar(menuBar);

        // Show the Mainframe in the center of the desktop screen
        MainFrame.setLocationRelativeTo(null);
        MainFrame.setVisible(true);
    }


    // listener for the menu items in MainFrame
    private static ActionListener menuListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            switch (e.getActionCommand()) {

            case GUI.MainFrame.EASY:
                field.setDifficultyFactor(Field.EASY);
                GameDisplay.setActive(true);
                break;

            case GUI.MainFrame.NORMAL:
                field.setDifficultyFactor(Field.NORMAL);
                GameDisplay.setActive(true);
                break;

            case GUI.MainFrame.HARD:
                field.setDifficultyFactor(Field.HARD);
                GameDisplay.setActive(true);
                break;
            }
        }

    };
};

【问题讨论】:

  • 什么时候在 SizeDialog 中设置私有 Model.Field 字段?现在我没有看到设置了 Field 类的实例。当您按下按钮时,这可能会给您一个空指针异常。
  • @Simon 你指的是像这样的字段 = new Model.Field();
  • 没错。或者像 GameDisplay 类的构造函数中的参数。您能否提供创建 GameDisplay 和 SizeDialog 的代码?
  • @Simon 我刚刚编辑了主条目以包含 MainFrame 和 App(P.S. 我已经实现了实例集并且方法没有改变按钮网格)

标签: java eclipse swing class reset


【解决方案1】:

Field 类的一个实例当前正在App 类中创建。 SizeDialog 类中的私有字段 field 当前未设置为 App 类已知的实例。此问题的解决方案是提供Field 实例作为参数。

一个可能的解决方案如下:

应用:

public class App {
    // Main Objects
    private static GUI.MainFrame MainFrame;
    private static GUI.GameDisplay GameDisplay;
    private static Model.Field field;
    public static GUI.SizeDialog SizeDialog;


    public static void main(String[] args) {
        // Setup of the Main Objects
        field = new Model.Field();
        GameDisplay = new GUI.GameDisplay(field);
        MainFrame = new MainFrame(GameDisplay, field);

        /* the rest of your code */
    }

    /* more App code */
}

主框架:

public class MainFrame extends JFrame {

    private static final long serialVersionUID = 1L;
    private static JPanel centerPanel;
    public static final String EASY = "Easy";
    public static final String NORMAL = "Normal";
    public static final String HARD = "Hard";

    private Model.Field field;

    public MainFrame(JPanel centerPanel, Model.Field field) {
        this.field = field;
        /* the rest of your code */
    }

    public JMenuBar setUpMenuBar(ActionListener listener) {
        // create the necessary menu items and menus
        JMenuBar menuBar = new JMenuBar();

        JMenu settingsMenu = new JMenu("Settings");
        JMenuItem size = new JMenuItem("Size");

        size.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object valueBox = new SizeDialog(field);
                ((Window) valueBox).setVisible(true);
            }
        });
        /* the rest of your code */
    }

    /* more MainFrame code */
}

大小对话框:

public class SizeDialog extends JDialog {

    private static final long serialVersionUID = 1L;
    private final Model.Field field;
    private GUI.GameDisplay GameDisplay;
    public static Integer currentRows = 4;
    public static Integer currentColumns = 4;

    public SizeDialog(final Model.Field field) {
        this.field = field;
        /* the rest of your code */
    }

    /* more SizeDialog code */
}

编辑:如this answer 中所述,匿名类中引用的对象必须是最终的。

【讨论】:

  • 我们现在有一个错误,如果没有最终方法就无法调用该方法,但是 field = new Model.Field();不会让它成为最终的
  • @Jackson 我不知道这个限制。我已将 SizeDialog 的字段变量和参数更改为 final。
  • 我仍然收到此错误:未解决的编译问题:无法引用以不同方法定义的内部类中的非最终变量字段(如果我将 SizeDialog(Model.Field field) 更改为SizeDialog(final Model.Field field) 它解决了这个问题但是 field = new Model.Field(); 要求它不是最终的
  • @Jackson 不幸的是,我现在无法为您提供更多帮助。我目前无法使用带有 Java 编译器的机器来尝试重现您的问题。我在一个在线编译器中尝试了一个小演示,它是在添加最终关键字后编译的。
  • 你是不是只对私有 final Model.Field 字段应用了 final;和 public final SizeDialog(Model.Field field) { in SizeDialog
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2021-02-28
  • 2015-11-19
  • 1970-01-01
相关资源
最近更新 更多