¿Cómo puedo guardar el estado de mi progtwig y luego cargarlo?

Estoy intentando guardar y volver a cargar el estado de mi progtwig Swing, que en este caso es un juego Minesweeper. Mi código para el tablero está abajo.

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

Hay muchas opciones posibles …

Tú podrías

Use la API de Properties , que proporciona funciones de guardar y cargar.

La API funciona como un Map , lo que le permite almacenar pares clave / valor, que puede guardar y cargar según sea necesario.

La API solo le permite almacenar valores de String , por lo que necesitaría convertir valores que no sean cadenas de forma manual.

Solo recuerda guardarlos ya que la API no persiste automáticamente los cambios

Eche un vistazo a Propiedades para más detalles.

Tú podrías

Haga rodar su propio archivo XML o use algo como JAXB que le permite vincular propiedades del objeto y exportarlas / importarlas a / desde XML

Este enfoque sería más flexible que usar Properties , pero introduce un nivel de complejidad

Tú podrías

Utilice la API de Preferences , que le permite almacenar valores de String y primitivos, sin la necesidad de realizar ningún tipo de conversión.

La API de Preferences también carga y almacena automáticamente su contenido, pero lo hará donde lo desee, por lo que perderá el control sobre dónde se almacena el contenido.

Tú podrías

Utilice una base de datos de usuario único / individual como H2 o HSQLDB, por ejemplo. Es un poco más complicado pero se ocupa de los requisitos básicos de almacenamiento.

También requeriría tiempo adicional para actualizar si cambia sus requisitos, sobre algo como usar Properties o Preferences y podría ser un poco exagerado si todo lo que está almacenando es la información de la celda … EN MI

Tú podrías

Trate de usar la serialización de objetos, pero la API nunca fue pensada para el almacenamiento a largo plazo de los estados de los objetos y es una bolsa de problemas y yo personalmente lo evitaría, pero ese soy yo.

En una aplicación Java, hay una gran variedad de formas de serializar la aplicación. datos.

  • Para los applets hay cookies.
  • Para aplicaciones. lanzado utilizando JWS, el Servicio de PersistenceService
  • Cualquier aplicación podría usar la API de Preferences .

Todas esas formas de serialización están pensadas para cosas que pueden codificarse en un nombre y valor basados ​​en cadenas.

  • Un archivo de Properties también es bueno para la información del tipo nombre / valor.
  • Para datos más complejos, crearía un bean y usaría XMLEncoder / XMLDecoder .
  • Un archivo Zip es bueno para serializar datos que pueden estar en muchas formas diferentes (por ejemplo, parte XML, propiedades de parte, algunas imágenes de captura de pantalla …).

Si usa las propiedades, archivo XML o Zip, un buen lugar para guardar la información. es un subdirectorio de user.home . Es reproducible y la aplicación. debería tener permisos de lectura / escritura.