如何保存程序的状态然后加载它?

问题描述 投票:0回答:2

我正在尝试保存并重新加载 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();

            }
        }
    }
}
java swing serialization imageicon
2个回答
7
投票

有很多可能的选择...

你可以

使用

Properties
API,它提供保存和加载功能。

API 的工作方式类似于

Map
,允许您存储键/值对,您可以根据需要保存和加载。

API 仅允许您存储

String
值,因此您需要手动转换非字符串值。

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

查看属性了解更多详细信息。

你可以

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

这种方法比使用

Properties
更灵活,但会带来一定程度的复杂性

你可以

使用

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

Preferences
API 还会自动加载和存储其内容,但它会在想要的位置执行此操作,因此您无法控制内容的存储位置。

你可以

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

如果您更改要求,还需要额外的时间来更新,而不是使用

Properties
Preferences
之类的东西,如果您存储的只是单元格数据,则可能有点过大了...恕我直言

你可以

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


1
投票

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

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

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

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

如果使用属性、XML 或 Zip 存档,这是保存信息的好地方。是

user.home
的子目录。它是可复制的并且是应用程序。应该有读/写权限。

© www.soinside.com 2019 - 2024. All rights reserved.