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: Minesweeper
* File: Minesweeper.java
* Created: 21.03.2019
* Author: Kai S. K. Engelbart */ 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(); } }