minesweeper/src/dev/kske/minesweeper/Minesweeper.java

218 lines
5.8 KiB
Java

package dev.kske.minesweeper;
import static dev.kske.minesweeper.BoardConfig.*;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
/**
* Project: <strong>Minesweeper</strong><br>
* File: <strong>Minesweeper.java</strong><br>
* Created: <strong>21.03.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong>
*/
public class Minesweeper {
private static final String VERSION = "1.1";
private JFrame mframe;
private Board board;
private Timer timer;
private int gameTime;
private ScoreManager scoreManager;
/**
* Launch the application.
*
* @param args command line arguments are ignored
*/
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
try {
Minesweeper window = new Minesweeper();
window.mframe.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* Create the application.
*
* @wbp.parser.entryPoint
*/
public Minesweeper() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.createLookAndFeel("Nimbus"));
} catch (Exception ex) {
ex.printStackTrace();
}
mframe = new JFrame();
mframe.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
scoreManager.saveScores();
}
});
mframe.setResizable(false);
mframe.setTitle("Minesweeper");
mframe.setBounds(100, 100, 359, 86);
mframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createMenuBar();
board = new Board();
board.init(EASY);
mframe.getContentPane().setLayout(new BorderLayout(0, 0));
mframe.getContentPane().add(board, BorderLayout.CENTER);
JPanel headerPanel = new JPanel();
mframe.getContentPane().add(headerPanel, BorderLayout.NORTH);
headerPanel.setLayout(new BorderLayout(0, 0));
JButton btnRestart = new JButton("Restart");
btnRestart.setHorizontalAlignment(SwingConstants.RIGHT);
headerPanel.add(btnRestart, BorderLayout.EAST);
JPanel panel = new JPanel();
headerPanel.add(panel, BorderLayout.WEST);
panel.setLayout(new BorderLayout(0, 0));
JLabel lblTime = new JLabel("Time:");
panel.add(lblTime, BorderLayout.NORTH);
timer = new Timer(1000, e -> lblTime.setText("Time: " + gameTime++ + "s"));
timer.setRepeats(true);
timer.setInitialDelay(0);
timer.setCoalesce(true);
JLabel lblRemainingMines = new JLabel("Remaining Mines: " + EASY.mines);
panel.add(lblRemainingMines, BorderLayout.SOUTH);
lblRemainingMines.setHorizontalAlignment(SwingConstants.LEFT);
btnRestart.addActionListener((evt) -> {
board.reset();
gameTime = 0;
timer.restart();
});
mframe.pack();
board.registerGameListener(new GameListener() {
@SuppressWarnings("incomplete-switch")
@Override
public void onGameOverEvent(GameOverEvent evt) {
timer.stop();
switch (evt.getGameState()) {
case LOST:
JOptionPane.showMessageDialog(mframe, "Game lost!");
break;
case WON:
JOptionPane.showMessageDialog(mframe, "Game won!");
scoreManager.addScore(evt);
}
}
@Override
public void onFlaggedTilesEvent(FlaggedTilesEvent evt) {
lblRemainingMines
.setText("Remaining Mines: " + (evt.getBoard().getMines() - evt.getFlagged()));
mframe.pack();
}
});
scoreManager = new ScoreManager();
scoreManager.loadScores();
timer.start();
}
private void createMenuBar() {
var menubar = new JMenuBar();
{
var gameMenu = new JMenu("Game");
var easyMenuItem = new JMenuItem("Easy");
var mediumMenuItem = new JMenuItem("Medium");
var hardMenuItem = new JMenuItem("Hard");
var customMenuItem = new JMenuItem("Custom");
gameMenu.setMnemonic(KeyEvent.VK_G);
easyMenuItem.setMnemonic(KeyEvent.VK_E);
mediumMenuItem.setMnemonic(KeyEvent.VK_M);
hardMenuItem.setMnemonic(KeyEvent.VK_H);
customMenuItem.setMnemonic(KeyEvent.VK_C);
easyMenuItem.addActionListener((evt) -> initGame(EASY));
mediumMenuItem.addActionListener((evt) -> initGame(MEDIUM));
hardMenuItem.addActionListener((evt) -> initGame(HARD));
customMenuItem.addActionListener((evt) -> {
BoardConfig cfg = new CustomDialog(mframe).showDialog();
if (cfg != null)
initGame(cfg);
});
gameMenu.add(easyMenuItem);
gameMenu.add(mediumMenuItem);
gameMenu.add(hardMenuItem);
gameMenu.addSeparator();
gameMenu.add(customMenuItem);
menubar.add(gameMenu);
}
{
var highscoreMenu = new JMenu("Highscores");
var easyMenuItem = new JMenuItem("Easy");
var mediumMenuItem = new JMenuItem("Medium");
var hardMenuItem = new JMenuItem("Hard");
highscoreMenu.setMnemonic(KeyEvent.VK_H);
easyMenuItem.setMnemonic(KeyEvent.VK_E);
mediumMenuItem.setMnemonic(KeyEvent.VK_M);
hardMenuItem.setMnemonic(KeyEvent.VK_H);
easyMenuItem.addActionListener((evt) -> scoreManager.displayEasy());
mediumMenuItem.addActionListener((evt) -> scoreManager.displayMedium());
hardMenuItem.addActionListener((evt) -> scoreManager.displayHard());
highscoreMenu.add(easyMenuItem);
highscoreMenu.add(mediumMenuItem);
highscoreMenu.add(hardMenuItem);
menubar.add(highscoreMenu);
}
{
var aboutMenuItem = new JMenuItem("About");
aboutMenuItem.addActionListener(
(evt) -> JOptionPane.showMessageDialog(board,
"Minesweeper version " + VERSION + "\nby Kai S. K. Engelbart"
)
);
menubar.add(aboutMenuItem);
}
mframe.setJMenuBar(menubar);
}
private void initGame(BoardConfig config) {
board.init(config);
gameTime = 0;
timer.restart();
mframe.pack();
}
}