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

我正在尝试保存并重新加载我的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  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 = 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 = 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  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  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  MINE_CELL) { field[cell] -= COVER_FOR_CELL; if (field[cell] == EMPTY_CELL) find_empty_cells(cell); } if (current_col = 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  MINE_CELL) { field[cell] -= COVER_FOR_CELL; if (field[cell] == EMPTY_CELL) find_empty_cells(cell); } cell = j + 1; if (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  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  MINE_CELL) { rep = true; if (field[(cRow * cols) + cCol]  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(); } } } } 

有多种可能的选择……

你可以

使用Properties API,它提供保存和加载function。

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

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

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

有关更多详细信息,请查看属性 。

你可以

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

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

你可以

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

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

你可以

例如,使用独立/单用户数据库,如H2或HSQLDB 。 它有点复杂,但确实照顾了基本的存储要求。

如果你改变你的要求,还需要额外的时间进行更新,比如使用PropertiesPreferences ,如果你要存储的只是单元数据,可能会有点过分…恕我直言

你可以

尝试使用对象序列化,但API从来没有用于对象状态的长期存储,而且它是一堆问题,我个人会避免它,但那就是我。

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

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

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

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

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