1

我正在尝试保存并重新加载我的 Swing 程序的状态,在本例中是扫雷游戏。我的董事会代码如下。

package mines;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Board extends JPanel {

    public static void main (String[] args)  {}
    private final int NUM_IMAGES = 13;
    private final int CELL_SIZE = 15;

    private final int COVER_FOR_CELL = 10;
    private final int MARK_FOR_CELL = 10;
    private final int EMPTY_CELL = 0;
    private final int MINE_CELL = 9;
    private final int COVERED_MINE_CELL = MINE_CELL + COVER_FOR_CELL;
    private final int MARKED_MINE_CELL = COVERED_MINE_CELL + MARK_FOR_CELL;

    private final int DRAW_MINE = 9;
    private final int DRAW_COVER = 10;
    private final int DRAW_MARK = 11;
    private final int DRAW_WRONG_MARK = 12;

    private int[] field;
    private boolean inGame;
    private int mines_left;
    private Image[] img;
    private int mines = 40;
    private int rows = 16;
    private int cols = 16;
    private int all_cells;
    private JLabel statusbar;

    public Board(JLabel statusbar) {

        this.statusbar = statusbar;

        img = new Image[NUM_IMAGES];

        for (int i = 0; i < NUM_IMAGES; i++) {
            img[i] =
                (new ImageIcon(this.getClass().getResource((i)
                    + ".png"))).getImage();
        }

        setDoubleBuffered(true);

        addMouseListener(new MinesAdapter());

        newGame();
    }


    public void newGame() {

        Random random;
        int current_col;

        int i = 0;
        int position = 0;
        int cell = 0;

        random = new Random();
        inGame = true;
    mines_left = mines;

    all_cells = rows * cols;
    field = new int[all_cells];

    for (i = 0; i < all_cells; i++)
        field[i] = COVER_FOR_CELL;

    statusbar.setText(Integer.toString(mines_left));


    i = 0;
    while (i < mines) {

        position = (int) (all_cells * random.nextDouble());

        if ((position < all_cells) &&
            (field[position] != COVERED_MINE_CELL)) {


            current_col = position % cols;
            field[position] = COVERED_MINE_CELL;
            i++;

            if (current_col > 0) { 
                cell = position - 1 - cols;
                if (cell >= 0)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;
                cell = position - 1;
                if (cell >= 0)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;

                cell = position + cols - 1;
                if (cell < all_cells)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;
            }

            cell = position - cols;
            if (cell >= 0)
                if (field[cell] != COVERED_MINE_CELL)
                    field[cell] += 1;
            cell = position + cols;
            if (cell < all_cells)
                if (field[cell] != COVERED_MINE_CELL)
                    field[cell] += 1;

            if (current_col < (cols - 1)) {
                cell = position - cols + 1;
                if (cell >= 0)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;
                cell = position + cols + 1;
                if (cell < all_cells)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;
                cell = position + 1;
                if (cell < all_cells)
                    if (field[cell] != COVERED_MINE_CELL)
                        field[cell] += 1;
            }
        }
    }
}


public void find_empty_cells(int j) {

    int current_col = j % cols;
    int cell;

    if (current_col > 0) { 
        cell = j - cols - 1;
        if (cell >= 0)
            if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
            }

        cell = j - 1;
        if (cell >= 0)
            if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
            }

        cell = j + cols - 1;
        if (cell < all_cells)
            if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
            }
    }

      cell = j - cols;
    if (cell >= 0)
        if (field[cell] > MINE_CELL) {
            field[cell] -= COVER_FOR_CELL;
            if (field[cell] == EMPTY_CELL)
                find_empty_cells(cell);
        }

       cell = j + cols;
       if (cell < all_cells)
        if (field[cell] > MINE_CELL) {
            field[cell] -= COVER_FOR_CELL;
            if (field[cell] == EMPTY_CELL)
                find_empty_cells(cell);
           }

          if (current_col < (cols - 1)) {
           cell = j - cols + 1;
             if (cell >= 0)
               if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
            }

           cell = j + cols + 1;
            if (cell < all_cells)
               if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
            }

          cell = j + 1;
           if (cell < all_cells)
            if (field[cell] > MINE_CELL) {
                field[cell] -= COVER_FOR_CELL;
                if (field[cell] == EMPTY_CELL)
                    find_empty_cells(cell);
               }
        }

       }

      public void paint(Graphics g) {

       int cell = 0;
        int uncover = 0;


        for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {

            cell = field[(i * cols) + j];

            if (inGame && cell == MINE_CELL)
                inGame = false;

            if (!inGame) {
                if (cell == COVERED_MINE_CELL) {
                    cell = DRAW_MINE;
                } else if (cell == MARKED_MINE_CELL) {
                    cell = DRAW_MARK;
                } else if (cell > COVERED_MINE_CELL) {
                    cell = DRAW_WRONG_MARK;
                } else if (cell > MINE_CELL) {
                    cell = DRAW_COVER;
                }


            } else {
                if (cell > COVERED_MINE_CELL)
                    cell = DRAW_MARK;
                else if (cell > MINE_CELL) {
                    cell = DRAW_COVER;
                    uncover++;
                }
            }

            g.drawImage(img[cell], (j * CELL_SIZE),
                (i * CELL_SIZE), this);
        }
       }


      if (uncover == 0 && inGame) {
        inGame = false;
        statusbar.setText("Game won");
      } else if (!inGame)
        statusbar.setText("Game lost");
       }




     class MinesAdapter extends MouseAdapter {
       public void mousePressed(MouseEvent e) {

        int x = e.getX();
        int y = e.getY();

        int cCol = x / CELL_SIZE;
        int cRow = y / CELL_SIZE;

        boolean rep = false;


          if (!inGame) {
            newGame();
            repaint();
          }


         if ((x < cols * CELL_SIZE) && (y < rows * CELL_SIZE)) {

            if (e.getButton() == MouseEvent.BUTTON3) {

                if (field[(cRow * cols) + cCol] > MINE_CELL) {
                    rep = true;

                    if (field[(cRow * cols) + cCol] <= COVERED_MINE_CELL) {
                        if (mines_left > 0) {
                            field[(cRow * cols) + cCol] += MARK_FOR_CELL;
                            mines_left--;
                            statusbar.setText(Integer.toString(mines_left));
                        } else
                            statusbar.setText("No marks left");
                    } else {

                        field[(cRow * cols) + cCol] -= MARK_FOR_CELL;
                        mines_left++;
                        statusbar.setText(Integer.toString(mines_left));
                    }
                }

            } else {

                if (field[(cRow * cols) + cCol] > COVERED_MINE_CELL) {
                    return;
                }

                if ((field[(cRow * cols) + cCol] > MINE_CELL) &&
                    (field[(cRow * cols) + cCol] < MARKED_MINE_CELL)) {

                    field[(cRow * cols) + cCol] -= COVER_FOR_CELL;
                    rep = true;

                    if (field[(cRow * cols) + cCol] == MINE_CELL)
                        inGame = false;
                    if (field[(cRow * cols) + cCol] == EMPTY_CELL)
                        find_empty_cells((cRow * cols) + cCol);
                }
            }

            if (rep)
                repaint();

            }
        }
    }
}
4

2 回答 2

7

有许多可能的选择...

你可以

使用Properties提供保存和加载功能的 API。

API 的工作方式类似于Map,允许您存储键/值对,您可以根据需要保存和加载。

该 API 仅允许您存储String值,因此您需要手动转换非字符串值。

请记住保存它们,因为 API 不会自动保存更改

查看属性以获取更多详细信息。

你可以

滚动您自己的 XML 文件或使用JAXB之类的东西,它允许您绑定对象的属性并将它们导出/导入到 XML 中/从 XML 中导出/导入它们

这种方法会比使用更灵活Properties,但会引入一定程度的复杂性

你可以

使用PreferencesAPI,它允许您存储String原始值,而无需执行任何类型的转换。

API 也会自动加载和存储它的Preferences内容,但它会在它想要的地方这样做,所以你无法控制内容的存储位置。

你可以

例如,使用H2HSQLDB等独立/单用户数据库。它有点复杂,但确实满足了基本的存储要求。

如果您更改您的要求,它还需要额外的时间来更新,例如使用PropertiesPreferences如果您存储的只是单元格数据,可能会有点矫枉过正......恕我直言

你可以

尝试使用对象序列化,但 API 从来都不是用于对象状态的长期存储,并且会带来很多问题,我个人会避免使用它,但这就是我。

于 2013-10-24T04:38:21.860 回答
1

在 Java 应用程序中,有多种方法可以序列化应用程序。数据。

  • 对于小程序,有 cookie。
  • 对于应用程序。使用 JWS 启动,PersistenceService
  • 任何应用程序。可能会使用PreferencesAPI。

所有这些形式的序列化都适用于可以编码为基于字符串的名称和值的内容。

  • 文件Properties也适用于名称/值类型信息。
  • 对于更复杂的数据,我会创建一个 bean 并使用XMLEncoder/ XMLDecoder
  • Zip 文件非常适合序列化可能采用多种不同形式的数据(例如,部分 XML、部分属性、一些屏幕截图图像......)。

如果使用属性、XML 或 Zip 存档,是保存信息的好地方。是 的子目录user.home。它是可重现的和应用程序。应该有读/写权限。

于 2015-01-12T06:41:33.053 回答