如何保存程序的状态然后加载它? [英] How can I save the state of my program and then load it?

查看:22
本文介绍了如何保存程序的状态然后加载它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试保存并重新加载 Swing 程序的状态,在本例中是扫雷游戏.我的电路板代码如下.

I'm trying to save and reload the state of my Swing program, which in this case is a Minesweeper game. My code for the board is below.

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();

            }
        }
    }
}

推荐答案

有多种可能的选择...

There are any number of possible choices...

使用 Properties API,它提供保存和加载功能.

Use the Properties API, which provides save and load functionality.

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

The API works like a Map, allowing you to store key/value pairs, which you can save and load as required.

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

The API only allows you to store String values, so you would need to convert non-String values manually.

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

Just remember to save them as the API does not automatically persist the changes

查看属性了解更多详情.

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

Roll you own XML file or use something like JAXB which allows you to bind properties of object and export/import them to/from XML

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

This approach would be more flexible then using Properties, but introduces a level of complexity

使用首选项 API,允许您存储 String 和原始值,而无需执行任何类型的转换.

Use the Preferences API, which allows you to store String and primitive values, with out the need to perform any type of converstion.

Preferences API 也会自动加载和存储它的内容,但它会在它想要的地方加载和存储,因此您无法控制内容的存储位置.

The Preferences API also automatically loads and stores it's content, but it will do so where it wants to, so you lose control over where the content is stored.

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

Use a stand alone/single user database like H2 or HSQLDB for example. It's a little more complicated but does take care of the basic storage requirements.

如果你改变你的要求,它也需要额外的时间来更新,比如使用 PropertiesPreferences 并且如果你存储的只是单元格数据...恕我直言

It would also require additional time to update should you change your requirements, over something like using Properties or Preferences and might be a little overkill if all you are storing is the cell data...IMHO

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

Try using object serialization, but the API was never meant for the long term storage of object states and carrie it's bag of problems and I would personally avoid it, but that's me.

这篇关于如何保存程序的状态然后加载它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆