Initial commit
This commit is contained in:
commit
8d1714777d
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.DS_Store
|
||||||
|
/bin
|
||||||
|
Minesweeper.dat
|
||||||
|
Minesweeper.jar
|
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Requirement
|
||||||
|
|
||||||
|
- Oracle JDK >= 1.8
|
||||||
|
- Add JDK's `/bin` directory into environment variable `$PATH`.
|
||||||
|
|
||||||
|
# Compilation
|
||||||
|
|
||||||
|
Execute `compile.sh` (`compile.bat` for Windows).
|
||||||
|
|
||||||
|
# Archive
|
||||||
|
|
||||||
|
Execute `archive.sh` (`archive.bat` for Windows).
|
8
archive.bat
Normal file
8
archive.bat
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@echo off
|
||||||
|
cd bin
|
||||||
|
jar cvfm "%~dp0Minesweeper.jar" "%~dp0manifest.mf" *
|
||||||
|
cd ..
|
||||||
|
echo.
|
||||||
|
echo 完成!
|
||||||
|
echo.
|
||||||
|
pause
|
4
archive.sh
Executable file
4
archive.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cd bin || exit
|
||||||
|
jar cvfm ../Minesweeper.jar ../manifest.mf ./*
|
10
compile.bat
Normal file
10
compile.bat
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@echo off
|
||||||
|
if exist bin (
|
||||||
|
del /Q bin
|
||||||
|
)
|
||||||
|
javac -d bin src\*.java
|
||||||
|
xcopy /Y "%~dp0res\*" "%~dp0bin"
|
||||||
|
echo.
|
||||||
|
echo 完成!
|
||||||
|
echo.
|
||||||
|
pause
|
7
compile.sh
Executable file
7
compile.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ -d bin ]; then rm -rf bin; fi
|
||||||
|
javac -d bin src/*.java
|
||||||
|
cp res/* bin
|
||||||
|
|
||||||
|
echo "完成!"
|
1
manifest.mf
Normal file
1
manifest.mf
Normal file
@ -0,0 +1 @@
|
|||||||
|
Main-Class: Main
|
BIN
res/410.png
Normal file
BIN
res/410.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
res/420.png
Normal file
BIN
res/420.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
res/430.png
Normal file
BIN
res/430.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
res/432.wav
Normal file
BIN
res/432.wav
Normal file
Binary file not shown.
BIN
res/433.wav
Normal file
BIN
res/433.wav
Normal file
Binary file not shown.
BIN
res/434.wav
Normal file
BIN
res/434.wav
Normal file
Binary file not shown.
BIN
res/icon.png
Normal file
BIN
res/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
150
src/BestTimesDialog.java
Normal file
150
src/BestTimesDialog.java
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
|
||||||
|
public class BestTimesDialog extends JDialog implements ActionListener, WindowListener {
|
||||||
|
private static final long serialVersionUID = -459646110674871028L;
|
||||||
|
|
||||||
|
private Minesweeper main;
|
||||||
|
|
||||||
|
private JLabel bRecord;
|
||||||
|
private JLabel iRecord;
|
||||||
|
private JLabel eRecord;
|
||||||
|
private JLabel iName;
|
||||||
|
private JLabel bName;
|
||||||
|
private JLabel eName;
|
||||||
|
|
||||||
|
public BestTimesDialog(Minesweeper main) {
|
||||||
|
super(main, "Fastest Mine Sweepers", true);
|
||||||
|
this.main = main;
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
JPanel panelTop = new JPanel();
|
||||||
|
JPanel panelBottom = new JPanel();
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
this.bRecord = new JLabel(data.getRecord(this.main.BEGINNER) + " seconds");
|
||||||
|
this.iRecord = new JLabel(data.getRecord(this.main.INTERMEDIATE) + " seconds");
|
||||||
|
this.eRecord = new JLabel(data.getRecord(this.main.EXPERT) + " seconds");
|
||||||
|
this.bName = new JLabel(data.getName(this.main.BEGINNER));
|
||||||
|
this.iName = new JLabel(data.getName(this.main.INTERMEDIATE));
|
||||||
|
this.eName = new JLabel(data.getName(this.main.EXPERT));
|
||||||
|
panelTop.setBorder(BorderFactory.createEmptyBorder(15, 10, 15, 10));
|
||||||
|
panelBottom.setBorder(BorderFactory.createEmptyBorder(0, 10, 15, 10));
|
||||||
|
add(panelTop, "North");
|
||||||
|
add(panelBottom);
|
||||||
|
panelTop.setLayout(new GridBagLayout());
|
||||||
|
panelBottom.setLayout(new GridBagLayout());
|
||||||
|
GridBagConstraints ct =
|
||||||
|
new GridBagConstraints(
|
||||||
|
3,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
GridBagConstraints.CENTER,
|
||||||
|
GridBagConstraints.NONE,
|
||||||
|
new Insets(2, 10, 2, 10),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
GridBagConstraints cb =
|
||||||
|
new GridBagConstraints(
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
GridBagConstraints.CENTER,
|
||||||
|
GridBagConstraints.NONE,
|
||||||
|
new Insets(2, 10, 2, 10),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
ct.gridx = 0;
|
||||||
|
ct.anchor = GridBagConstraints.WEST;
|
||||||
|
ct.gridy = 0;
|
||||||
|
panelTop.add(new JLabel("Beginner:"), ct);
|
||||||
|
ct.gridy = 1;
|
||||||
|
panelTop.add(new JLabel("Intermediate:"), ct);
|
||||||
|
ct.gridy = 2;
|
||||||
|
panelTop.add(new JLabel("Expert:"), ct);
|
||||||
|
ct.gridx = 1;
|
||||||
|
ct.gridy = GridBagConstraints.RELATIVE;
|
||||||
|
ct.weightx = 1.0;
|
||||||
|
ct.anchor = GridBagConstraints.CENTER;
|
||||||
|
ct.gridy = 0;
|
||||||
|
panelTop.add(this.bRecord, ct);
|
||||||
|
ct.gridy = 1;
|
||||||
|
panelTop.add(this.iRecord, ct);
|
||||||
|
ct.gridy = 2;
|
||||||
|
panelTop.add(this.eRecord, ct);
|
||||||
|
ct.gridx = 2;
|
||||||
|
ct.gridy = 0;
|
||||||
|
panelTop.add(this.bName, ct);
|
||||||
|
ct.gridy = 1;
|
||||||
|
panelTop.add(this.iName, ct);
|
||||||
|
ct.gridy = 2;
|
||||||
|
panelTop.add(this.eName, ct);
|
||||||
|
cb.gridx = 0;
|
||||||
|
cb.gridy = 0;
|
||||||
|
JButton reset = new JButton("Reset Scores");
|
||||||
|
panelBottom.add(reset, cb);
|
||||||
|
reset.addActionListener(this);
|
||||||
|
cb.gridx = 1;
|
||||||
|
cb.gridy = 0;
|
||||||
|
JButton ok = new JButton("OK");
|
||||||
|
panelBottom.add(ok, cb);
|
||||||
|
this.getRootPane().setDefaultButton(ok);
|
||||||
|
ok.addActionListener(this);
|
||||||
|
pack();
|
||||||
|
setResizable(false);
|
||||||
|
Rectangle screenSize = getGraphicsConfiguration().getBounds();
|
||||||
|
setLocation(
|
||||||
|
screenSize.x + screenSize.width / 2 - getSize().width / 2,
|
||||||
|
screenSize.y + screenSize.height / 2 - getSize().height / 2);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("Reset Scores")) {
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
data.setRecord(0, 999);
|
||||||
|
data.setRecord(1, 999);
|
||||||
|
data.setRecord(2, 999);
|
||||||
|
data.setName(0, "Anonymous");
|
||||||
|
data.setName(1, "Anonymous");
|
||||||
|
data.setName(2, "Anonymous");
|
||||||
|
this.bRecord.setText("999 seconds");
|
||||||
|
this.iRecord.setText("999 seconds");
|
||||||
|
this.eRecord.setText("999 seconds");
|
||||||
|
this.bName.setText("Anonymous");
|
||||||
|
this.iName.setText("Anonymous");
|
||||||
|
this.eName.setText("Anonymous");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {}
|
||||||
|
}
|
170
src/Board.java
Normal file
170
src/Board.java
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
|
||||||
|
|
||||||
|
public class Board extends JPanel {
|
||||||
|
private static final long serialVersionUID = -8979636904753517635L;
|
||||||
|
|
||||||
|
private Minesweeper main;
|
||||||
|
|
||||||
|
private Tile[][] tiles;
|
||||||
|
|
||||||
|
private int height;
|
||||||
|
private int width;
|
||||||
|
private int numOfMines;
|
||||||
|
|
||||||
|
private void addMines() {
|
||||||
|
if (this.numOfMines >= this.width * this.height) {
|
||||||
|
this.numOfMines = this.width * this.height - 1;
|
||||||
|
}
|
||||||
|
int nextRow, nextCol;
|
||||||
|
int i = 0;
|
||||||
|
while (i < this.numOfMines) {
|
||||||
|
nextRow = Math.round((float) Math.random() * (this.height - 1));
|
||||||
|
nextCol = Math.round((float) Math.random() * (this.width - 1));
|
||||||
|
if (!this.tiles[nextRow][nextCol].isMine()) {
|
||||||
|
this.tiles[nextRow][nextCol].setMine();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setTileValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTileValues() {
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
if (this.tiles[i][j].isMine()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int mines = 0;
|
||||||
|
for (int k = i - 1; k <= i + 1; k += 1) {
|
||||||
|
for (int l = j - 1; l <= j + 1; l += 1) {
|
||||||
|
if (!(k < 0 || l < 0 || k >= this.height || l >= this.width)
|
||||||
|
&& !(k == i && l == j)
|
||||||
|
&& this.tiles[k][l].isMine()) {
|
||||||
|
mines += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tiles[i][j].setValue(mines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.main.getStorage().isCreepy()) {
|
||||||
|
this.addDuds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDuds() {
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
if (this.tiles[i][j].isMine() && Math.round((float) Math.random() * 5) == 0) {
|
||||||
|
this.tiles[i][j].setDud();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(Minesweeper main) {
|
||||||
|
this.main = main;
|
||||||
|
setBackground(new Color(192, 192, 192));
|
||||||
|
setBorder(
|
||||||
|
BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createEmptyBorder(5, 5, 5, 5),
|
||||||
|
new ButtonBorder(
|
||||||
|
Color.white, Color.white, new Color(128, 128, 128), new Color(128, 128, 128))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Minesweeper getMain() {
|
||||||
|
return this.main;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMines() {
|
||||||
|
return this.numOfMines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoard(int width, int height, int mines) {
|
||||||
|
setVisible(false);
|
||||||
|
this.height = height;
|
||||||
|
this.width = width;
|
||||||
|
this.numOfMines = mines;
|
||||||
|
setLayout(new GridLayout(this.height, this.width, 0, 0));
|
||||||
|
removeAll();
|
||||||
|
this.tiles = new Tile[this.height][this.width];
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
add(this.tiles[i][j] = new Tile(i, j, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.addMines();
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand(int row, int col) {
|
||||||
|
setVisible(false);
|
||||||
|
for (int i = row - 1; i <= row + 1; i += 1) {
|
||||||
|
for (int j = col - 1; j <= col + 1; j += 1) {
|
||||||
|
if (!(i < 0 || j < 0 || i >= this.height || j >= this.width) && !(i == row && j == col)) {
|
||||||
|
Tile tile = this.tiles[i][j];
|
||||||
|
if (!tile.isUncovered() && !tile.isFlagged() && !tile.isUnsure() && !tile.isDud()) {
|
||||||
|
tile.uncover(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showMines() {
|
||||||
|
setVisible(false);
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
Tile tile = this.tiles[i][j];
|
||||||
|
if (tile.isMine()
|
||||||
|
&& !tile.isUncovered()
|
||||||
|
&& !tile.isFlagged()
|
||||||
|
&& !tile.isUnsure()
|
||||||
|
&& !tile.isDud()) {
|
||||||
|
tile.setTileIcon("covered mine");
|
||||||
|
} else if ((!tile.isMine() || tile.isDud()) && tile.isFlagged()) {
|
||||||
|
tile.setTileIcon("misflagged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showFlags() {
|
||||||
|
setVisible(false);
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
Tile tile = this.tiles[i][j];
|
||||||
|
if (tile.isMine() && !tile.isUncovered() && !tile.isFlagged()) {
|
||||||
|
tile.setTileIcon("flagged");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAllMouseListeners() {
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
this.tiles[i][j].removeMouseListener(this.tiles[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkWon(boolean expanding) {
|
||||||
|
for (int i = 0; i < this.height; i += 1) {
|
||||||
|
for (int j = 0; j < this.width; j += 1) {
|
||||||
|
Tile tile = this.tiles[i][j];
|
||||||
|
if ((tile.isFlagged() && !tile.isMine())
|
||||||
|
|| (!tile.isUncovered() && !tile.isFlagged() && !tile.isMine())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.main.complete(expanding);
|
||||||
|
}
|
||||||
|
}
|
75
src/CounterDisplay.java
Normal file
75
src/CounterDisplay.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
|
||||||
|
|
||||||
|
public class CounterDisplay extends JPanel {
|
||||||
|
private static final long serialVersionUID = 8590228173889847000L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
|
||||||
|
private Digit hundred;
|
||||||
|
private Digit tenth;
|
||||||
|
private Digit first;
|
||||||
|
|
||||||
|
private int mines;
|
||||||
|
|
||||||
|
public CounterDisplay(Board board) {
|
||||||
|
this.board = board;
|
||||||
|
this.hundred = new Digit(this.board);
|
||||||
|
this.tenth = new Digit(this.board);
|
||||||
|
this.first = new Digit(this.board);
|
||||||
|
this.mines = this.board.getMines();
|
||||||
|
this.updateDisplay();
|
||||||
|
setBackground(new Color(192, 192, 192));
|
||||||
|
setBorder(
|
||||||
|
BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createEmptyBorder(5, 5, 5, 5),
|
||||||
|
new ButtonBorder(
|
||||||
|
Color.white, Color.white, new Color(128, 128, 128), new Color(128, 128, 128))));
|
||||||
|
setVisible(false);
|
||||||
|
setLayout(new GridLayout(1, 3, 0, 0));
|
||||||
|
removeAll();
|
||||||
|
add(this.hundred);
|
||||||
|
add(this.tenth);
|
||||||
|
add(this.first);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increase() {
|
||||||
|
this.mines += 1;
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decrease() {
|
||||||
|
this.mines -= 1;
|
||||||
|
if (this.mines < 0) {
|
||||||
|
this.negativeLoop();
|
||||||
|
} else {
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.mines = this.board.getMines();
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
this.mines = 0;
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDisplay() {
|
||||||
|
this.hundred.setDigitIcon(String.valueOf(mines / 100));
|
||||||
|
this.tenth.setDigitIcon(String.valueOf(mines / 10 % 10));
|
||||||
|
this.first.setDigitIcon(String.valueOf(mines % 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void negativeLoop() {
|
||||||
|
this.hundred.setDigitIcon("-");
|
||||||
|
int temp = Math.abs(mines) % 100;
|
||||||
|
this.tenth.setDigitIcon(String.valueOf(temp / 10 % 10));
|
||||||
|
this.first.setDigitIcon(String.valueOf(temp % 10));
|
||||||
|
}
|
||||||
|
}
|
154
src/CustomDialog.java
Normal file
154
src/CustomDialog.java
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
|
||||||
|
public class CustomDialog extends JDialog implements ActionListener, WindowListener {
|
||||||
|
private static final long serialVersionUID = 3593586540539735229L;
|
||||||
|
|
||||||
|
private Minesweeper main;
|
||||||
|
|
||||||
|
private JTextField height = new JTextField(5);
|
||||||
|
private JTextField width = new JTextField(5);
|
||||||
|
private JTextField mines = new JTextField(5);
|
||||||
|
|
||||||
|
private int hValue;
|
||||||
|
private int wValue;
|
||||||
|
private int mValue;
|
||||||
|
|
||||||
|
public CustomDialog(Minesweeper main) {
|
||||||
|
super(main, "Custom Field", true);
|
||||||
|
this.main = main;
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
this.hValue = data.getHeight();
|
||||||
|
this.wValue = data.getWidth();
|
||||||
|
this.mValue = data.getMines();
|
||||||
|
this.height.setText(String.valueOf(this.hValue));
|
||||||
|
this.width.setText(String.valueOf(this.wValue));
|
||||||
|
this.mines.setText(String.valueOf(this.mValue));
|
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(30, 10, 30, 10));
|
||||||
|
add(panel);
|
||||||
|
panel.setLayout(new GridBagLayout());
|
||||||
|
GridBagConstraints c =
|
||||||
|
new GridBagConstraints(
|
||||||
|
3,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
GridBagConstraints.CENTER,
|
||||||
|
GridBagConstraints.NONE,
|
||||||
|
new Insets(2, 10, 2, 10),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
c.gridx = 3;
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
c.gridy = 0;
|
||||||
|
JButton ok = new JButton("OK");
|
||||||
|
panel.add(ok, c);
|
||||||
|
this.getRootPane().setDefaultButton(ok);
|
||||||
|
ok.addActionListener(this);
|
||||||
|
c.gridx = 3;
|
||||||
|
c.gridy = 2;
|
||||||
|
JButton cancel = new JButton("Cancel");
|
||||||
|
panel.add(cancel, c);
|
||||||
|
cancel.addActionListener(this);
|
||||||
|
c.gridx = 0;
|
||||||
|
c.anchor = GridBagConstraints.EAST;
|
||||||
|
c.gridy = 0;
|
||||||
|
panel.add(new JLabel("Height:"), c);
|
||||||
|
c.gridy = 1;
|
||||||
|
panel.add(new JLabel("Width:"), c);
|
||||||
|
c.gridy = 2;
|
||||||
|
panel.add(new JLabel("Mines:"), c);
|
||||||
|
c.gridx = 1;
|
||||||
|
c.gridy = GridBagConstraints.RELATIVE;
|
||||||
|
c.weightx = 1.0;
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
c.anchor = GridBagConstraints.CENTER;
|
||||||
|
c.gridy = 0;
|
||||||
|
panel.add(height, c);
|
||||||
|
c.gridy = 1;
|
||||||
|
panel.add(width, c);
|
||||||
|
c.gridy = 2;
|
||||||
|
panel.add(mines, c);
|
||||||
|
pack();
|
||||||
|
setResizable(false);
|
||||||
|
Rectangle screenSize = getGraphicsConfiguration().getBounds();
|
||||||
|
setLocation(
|
||||||
|
screenSize.x + screenSize.width / 2 - getSize().width / 2,
|
||||||
|
screenSize.y + screenSize.height / 2 - getSize().height / 2);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setValues() {
|
||||||
|
try {
|
||||||
|
this.wValue = Integer.decode(width.getText()).intValue();
|
||||||
|
if (this.wValue < 9) {
|
||||||
|
this.wValue = 9;
|
||||||
|
} else if (this.wValue > 30) {
|
||||||
|
this.wValue = 30;
|
||||||
|
}
|
||||||
|
this.hValue = Integer.decode(height.getText()).intValue();
|
||||||
|
if (this.hValue < 9) {
|
||||||
|
this.hValue = 9;
|
||||||
|
} else if (this.hValue > 24) {
|
||||||
|
this.hValue = 24;
|
||||||
|
}
|
||||||
|
this.mValue = Integer.decode(mines.getText()).intValue();
|
||||||
|
if (this.mValue < 10) {
|
||||||
|
this.mValue = 10;
|
||||||
|
} else if (this.mValue > 668) {
|
||||||
|
this.mValue = 668;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeightValue() {
|
||||||
|
return this.hValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidthValue() {
|
||||||
|
return this.wValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinesValue() {
|
||||||
|
return this.mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("Cancel") || this.setValues()) {
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {}
|
||||||
|
}
|
49
src/Digit.java
Normal file
49
src/Digit.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Digit extends JLabel {
|
||||||
|
private static final long serialVersionUID = -4719882476458914430L;
|
||||||
|
private Board board;
|
||||||
|
private BufferedImage image;
|
||||||
|
|
||||||
|
private int value = 0;
|
||||||
|
|
||||||
|
private final int HEIGHT = 23;
|
||||||
|
private final int WIDTH = 13;
|
||||||
|
|
||||||
|
public Digit(Board board) {
|
||||||
|
super("", JLabel.CENTER);
|
||||||
|
this.board = board;
|
||||||
|
this.image = this.board.getMain().getImage().getDigit();
|
||||||
|
this.setDigitIcon("0");
|
||||||
|
setVerticalAlignment(JLabel.CENTER);
|
||||||
|
setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
setPreferredSize(new Dimension(this.WIDTH, this.HEIGHT));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int topMargin(String number) {
|
||||||
|
String[] numbers = {
|
||||||
|
"-", " ", "9", "8", "7", "6",
|
||||||
|
"5", "4", "3", "2", "1", "0"
|
||||||
|
};
|
||||||
|
for (int i = 0; i < numbers.length; i += 1) {
|
||||||
|
if (numbers[i].equals(number)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDigitIcon(String value) {
|
||||||
|
setIcon(
|
||||||
|
new ImageIcon(
|
||||||
|
this.image.getSubimage(
|
||||||
|
0, this.HEIGHT * this.topMargin(value), this.WIDTH, this.HEIGHT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) {
|
||||||
|
this.value = value;
|
||||||
|
this.setDigitIcon(String.valueOf(this.value));
|
||||||
|
}
|
||||||
|
}
|
43
src/Info.java
Normal file
43
src/Info.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
|
||||||
|
|
||||||
|
public class Info extends JPanel {
|
||||||
|
private static final long serialVersionUID = 3806487248823604535L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
private CounterDisplay counter;
|
||||||
|
private Smiley smiley;
|
||||||
|
private TimerDisplay timer;
|
||||||
|
|
||||||
|
public Info(Minesweeper main) {
|
||||||
|
this.board = main.getBoard();
|
||||||
|
this.counter = new CounterDisplay(this.board);
|
||||||
|
this.smiley = new Smiley(this.board);
|
||||||
|
this.timer = new TimerDisplay(this.board);
|
||||||
|
setBackground(new Color(192, 192, 192));
|
||||||
|
setBorder(
|
||||||
|
BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createEmptyBorder(5, 5, 0, 5),
|
||||||
|
new ButtonBorder(
|
||||||
|
Color.white, Color.white, new Color(128, 128, 128), new Color(128, 128, 128))));
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
add(this.counter, "West");
|
||||||
|
add(this.smiley, "Center");
|
||||||
|
add(this.timer, "East");
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CounterDisplay getCounter() {
|
||||||
|
return this.counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Smiley getSmiley() {
|
||||||
|
return this.smiley;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimerDisplay getTimer() {
|
||||||
|
return this.timer;
|
||||||
|
}
|
||||||
|
}
|
5
src/Main.java
Normal file
5
src/Main.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new Minesweeper();
|
||||||
|
}
|
||||||
|
}
|
118
src/Menubar.java
Normal file
118
src/Menubar.java
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Menubar extends JMenuBar implements ActionListener {
|
||||||
|
private static final long serialVersionUID = 865388774192274414L;
|
||||||
|
|
||||||
|
private Minesweeper main;
|
||||||
|
|
||||||
|
private JCheckBoxMenuItem creepy;
|
||||||
|
private JCheckBoxMenuItem sound;
|
||||||
|
|
||||||
|
public Menubar(Minesweeper main) {
|
||||||
|
this.main = main;
|
||||||
|
JMenu game = new JMenu("Game");
|
||||||
|
add(game);
|
||||||
|
JMenuItem newGame = new JMenuItem("New");
|
||||||
|
game.add(newGame);
|
||||||
|
newGame.addActionListener(this);
|
||||||
|
game.addSeparator();
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
JRadioButtonMenuItem beginner =
|
||||||
|
new JRadioButtonMenuItem(
|
||||||
|
"Beginner", (data.getDifficulty() == this.main.BEGINNER) ? true : false);
|
||||||
|
JRadioButtonMenuItem intermediate =
|
||||||
|
new JRadioButtonMenuItem(
|
||||||
|
"Intermediate", (data.getDifficulty() == this.main.INTERMEDIATE) ? true : false);
|
||||||
|
JRadioButtonMenuItem expert =
|
||||||
|
new JRadioButtonMenuItem(
|
||||||
|
"Expert", (data.getDifficulty() == this.main.EXPERT) ? true : false);
|
||||||
|
JRadioButtonMenuItem custom =
|
||||||
|
new JRadioButtonMenuItem(
|
||||||
|
"Custom...", (data.getDifficulty() == this.main.CUSTOM) ? true : false);
|
||||||
|
this.creepy = new JCheckBoxMenuItem("Creepy Mode", (data.isCreepy()) ? true : false);
|
||||||
|
game.add(beginner);
|
||||||
|
game.add(intermediate);
|
||||||
|
game.add(expert);
|
||||||
|
game.add(custom);
|
||||||
|
game.add(creepy);
|
||||||
|
ButtonGroup difficulties = new ButtonGroup();
|
||||||
|
difficulties.add(beginner);
|
||||||
|
difficulties.add(intermediate);
|
||||||
|
difficulties.add(expert);
|
||||||
|
difficulties.add(custom);
|
||||||
|
beginner.addActionListener(this);
|
||||||
|
intermediate.addActionListener(this);
|
||||||
|
expert.addActionListener(this);
|
||||||
|
custom.addActionListener(this);
|
||||||
|
custom.setActionCommand("Custom");
|
||||||
|
creepy.addActionListener(this);
|
||||||
|
game.addSeparator();
|
||||||
|
this.sound = new JCheckBoxMenuItem("Sound", (data.isSoundEnabled()) ? true : false);
|
||||||
|
game.add(sound);
|
||||||
|
sound.addActionListener(this);
|
||||||
|
game.addSeparator();
|
||||||
|
JMenuItem bestTimes = new JMenuItem("Best Times...");
|
||||||
|
game.add(bestTimes);
|
||||||
|
bestTimes.addActionListener(this);
|
||||||
|
bestTimes.setActionCommand("Best Times");
|
||||||
|
game.addSeparator();
|
||||||
|
JMenuItem exit = new JMenuItem("Exit");
|
||||||
|
game.add(exit);
|
||||||
|
exit.addActionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("New")) {
|
||||||
|
this.main.newGame();
|
||||||
|
} else {
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
if (cmd.equals("Beginner")) {
|
||||||
|
data.setDifficulty(this.main.BEGINNER);
|
||||||
|
this.main.newGame();
|
||||||
|
} else if (cmd.equals("Intermediate")) {
|
||||||
|
data.setDifficulty(this.main.INTERMEDIATE);
|
||||||
|
this.main.newGame();
|
||||||
|
} else if (cmd.equals("Expert")) {
|
||||||
|
data.setDifficulty(this.main.EXPERT);
|
||||||
|
this.main.newGame();
|
||||||
|
} else if (cmd.equals("Custom")) {
|
||||||
|
CustomDialog dialog = new CustomDialog(this.main);
|
||||||
|
data.setDifficulty(this.main.CUSTOM);
|
||||||
|
data.setHeight(dialog.getHeightValue());
|
||||||
|
data.setWidth(dialog.getWidthValue());
|
||||||
|
data.setMines(dialog.getMinesValue());
|
||||||
|
this.main.newGame();
|
||||||
|
} else if (cmd.equals("Creepy Mode")) {
|
||||||
|
data.switchCreepy();
|
||||||
|
if (!data.isSoundEnabled()) {
|
||||||
|
data.switchSound();
|
||||||
|
this.sound.setSelected(true);
|
||||||
|
}
|
||||||
|
if (this.main.isGameStarted()) {
|
||||||
|
this.main.newGame();
|
||||||
|
}
|
||||||
|
} else if (cmd.equals("Sound")) {
|
||||||
|
data.switchSound();
|
||||||
|
if (data.isCreepy()) {
|
||||||
|
data.switchCreepy();
|
||||||
|
this.creepy.setSelected(false);
|
||||||
|
this.main.newGame();
|
||||||
|
} else if (this.main.isGameStarted()) {
|
||||||
|
PlaySound play = this.main.getPlay();
|
||||||
|
if (play.isPlaying()) {
|
||||||
|
play.stop();
|
||||||
|
} else {
|
||||||
|
play.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (cmd.equals("Best Times")) {
|
||||||
|
new BestTimesDialog(this.main);
|
||||||
|
} else if (cmd.equals("Exit")) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
151
src/Minesweeper.java
Normal file
151
src/Minesweeper.java
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Minesweeper extends JFrame {
|
||||||
|
private static final long serialVersionUID = -711696178703199107L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
private Info info;
|
||||||
|
private PlaySound play;
|
||||||
|
private Resource images;
|
||||||
|
private Storage data;
|
||||||
|
|
||||||
|
private boolean gameStarted;
|
||||||
|
|
||||||
|
private final String RES_GAME_ICON = "icon.png";
|
||||||
|
|
||||||
|
public final int BEGINNER = 0;
|
||||||
|
public final int INTERMEDIATE = 1;
|
||||||
|
public final int EXPERT = 2;
|
||||||
|
public final int CUSTOM = 3;
|
||||||
|
|
||||||
|
private void setLocationCenter() {
|
||||||
|
Rectangle screen = getGraphicsConfiguration().getBounds();
|
||||||
|
setLocation(
|
||||||
|
screen.x + screen.width / 2 - getSize().width / 2,
|
||||||
|
screen.y + screen.height / 2 - getSize().height / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Minesweeper() {
|
||||||
|
super("Minesweeper");
|
||||||
|
this.data = new Storage();
|
||||||
|
this.images = new Resource();
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource(RES_GAME_ICON)));
|
||||||
|
setJMenuBar(new Menubar(this));
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
this.data = new Storage();
|
||||||
|
this.board = new Board(this);
|
||||||
|
this.board.setBoard(
|
||||||
|
this.data.getWidth(),
|
||||||
|
this.data.getHeight(),
|
||||||
|
this.data.getMines()); // must call setBoard before create instances of Info
|
||||||
|
this.info = new Info(this);
|
||||||
|
this.play = new PlaySound();
|
||||||
|
this.gameStarted = false;
|
||||||
|
add(this.info, "North");
|
||||||
|
add(this.board);
|
||||||
|
pack();
|
||||||
|
setResizable(false);
|
||||||
|
this.setLocationCenter();
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newGame() {
|
||||||
|
this.board.setBoard(this.data.getWidth(), this.data.getHeight(), this.data.getMines());
|
||||||
|
pack();
|
||||||
|
if (this.isGameStarted()) {
|
||||||
|
this.info.getTimer().stop();
|
||||||
|
if (this.data.isSoundEnabled()) {
|
||||||
|
this.play.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.info.getCounter().reset();
|
||||||
|
this.info.getSmiley().setSmileyIcon("smile");
|
||||||
|
this.info.getTimer().reset();
|
||||||
|
this.stopGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delGame() {
|
||||||
|
this.stopGame();
|
||||||
|
if (this.data.isSoundEnabled()) {
|
||||||
|
this.play.stop();
|
||||||
|
this.play.boom();
|
||||||
|
}
|
||||||
|
this.info.getTimer().stop();
|
||||||
|
this.info.getSmiley().setSmileyIcon("death");
|
||||||
|
this.board.removeAllMouseListeners();
|
||||||
|
this.board.showMines();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board getBoard() {
|
||||||
|
return this.board;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Info getInfo() {
|
||||||
|
return this.info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaySound getPlay() {
|
||||||
|
return this.play;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource getImage() {
|
||||||
|
return this.images;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Storage getStorage() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGameStarted() {
|
||||||
|
return this.gameStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startGame() {
|
||||||
|
this.gameStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopGame() {
|
||||||
|
this.gameStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void complete(boolean expanding) {
|
||||||
|
this.stopGame();
|
||||||
|
this.info.getTimer().stop();
|
||||||
|
this.info.getSmiley().setSmileyIcon("boss");
|
||||||
|
this.board.removeAllMouseListeners();
|
||||||
|
this.board.showFlags();
|
||||||
|
this.info.getCounter().clear();
|
||||||
|
if (this.data.isSoundEnabled() && !this.data.isCreepy() && !expanding) {
|
||||||
|
this.play.stop();
|
||||||
|
this.play.win();
|
||||||
|
}
|
||||||
|
if (this.isNewRecord() && !this.data.isCreepy()) {
|
||||||
|
new NewRecordDialog(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNewRecord() {
|
||||||
|
int seconds = this.info.getTimer().getTime();
|
||||||
|
switch (this.data.getDifficulty()) {
|
||||||
|
case 0:
|
||||||
|
if (seconds < this.data.getRecord(this.BEGINNER)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (seconds < this.data.getRecord(this.INTERMEDIATE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (seconds < this.data.getRecord(this.EXPERT)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
98
src/NewRecordDialog.java
Normal file
98
src/NewRecordDialog.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
|
||||||
|
public class NewRecordDialog extends JDialog implements ActionListener, WindowListener {
|
||||||
|
private static final long serialVersionUID = -7317311608209462993L;
|
||||||
|
|
||||||
|
private Minesweeper main;
|
||||||
|
|
||||||
|
private JTextField name;
|
||||||
|
|
||||||
|
public NewRecordDialog(Minesweeper main) {
|
||||||
|
super(main, "", true);
|
||||||
|
this.main = main;
|
||||||
|
this.name = new JTextField("Anonymous");
|
||||||
|
JPanel panel = new JPanel();
|
||||||
|
add(panel);
|
||||||
|
panel.setLayout(new GridBagLayout());
|
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
|
||||||
|
GridBagConstraints c =
|
||||||
|
new GridBagConstraints(
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
GridBagConstraints.CENTER,
|
||||||
|
GridBagConstraints.NONE,
|
||||||
|
new Insets(15, 15, 15, 15),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
panel.add(
|
||||||
|
new JLabel(
|
||||||
|
"<html><center>You have the fastest time<br>for "
|
||||||
|
+ this.getLevel()
|
||||||
|
+ " level.<br>Please enter your name.</center></html>"),
|
||||||
|
c);
|
||||||
|
c.gridy = 1;
|
||||||
|
panel.add(this.name, c);
|
||||||
|
c.gridy = 2;
|
||||||
|
JButton ok = new JButton("OK");
|
||||||
|
panel.add(ok, c);
|
||||||
|
this.getRootPane().setDefaultButton(ok);
|
||||||
|
ok.addActionListener(this);
|
||||||
|
pack();
|
||||||
|
setResizable(false);
|
||||||
|
Rectangle screenSize = getGraphicsConfiguration().getBounds();
|
||||||
|
setLocation(
|
||||||
|
screenSize.x + screenSize.width / 2 - getSize().width / 2,
|
||||||
|
screenSize.y + screenSize.height / 2 - getSize().height / 2);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLevel() {
|
||||||
|
switch (this.main.getStorage().getDifficulty()) {
|
||||||
|
case 0:
|
||||||
|
return "beginner";
|
||||||
|
case 1:
|
||||||
|
return "intermediate";
|
||||||
|
case 2:
|
||||||
|
return "expert";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Storage data = this.main.getStorage();
|
||||||
|
data.setRecord(data.getDifficulty(), this.main.getInfo().getTimer().getTime());
|
||||||
|
data.setName(data.getDifficulty(), this.name.getText());
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {}
|
||||||
|
}
|
64
src/PlaySound.java
Normal file
64
src/PlaySound.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import javax.sound.sampled.*;
|
||||||
|
|
||||||
|
public class PlaySound {
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
private boolean playing;
|
||||||
|
|
||||||
|
private final String RES_TICK = "432.wav";
|
||||||
|
private final String RES_WIN = "433.wav";
|
||||||
|
private final String RES_BOOM = "434.wav";
|
||||||
|
|
||||||
|
public PlaySound() {
|
||||||
|
this.playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlaying() {
|
||||||
|
return this.playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play(String filename) {
|
||||||
|
URL f = getClass().getResource(filename);
|
||||||
|
try {
|
||||||
|
AudioInputStream in = AudioSystem.getAudioInputStream(f);
|
||||||
|
Clip clip = AudioSystem.getClip();
|
||||||
|
clip.open(in);
|
||||||
|
clip.start();
|
||||||
|
} catch (UnsupportedAudioFileException e) {
|
||||||
|
} catch (IOException e) {
|
||||||
|
} catch (LineUnavailableException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
this.playing = true;
|
||||||
|
this.timer = new Timer();
|
||||||
|
TimerTask tt =
|
||||||
|
new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
play(RES_TICK);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timer.scheduleAtFixedRate(tt, 0, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void win() {
|
||||||
|
this.play(this.RES_WIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void boom() {
|
||||||
|
this.play(this.RES_BOOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (this.playing) {
|
||||||
|
this.timer.cancel();
|
||||||
|
this.playing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/Resource.java
Normal file
42
src/Resource.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Resource {
|
||||||
|
private BufferedImage digit;
|
||||||
|
private BufferedImage smiley;
|
||||||
|
private BufferedImage tile;
|
||||||
|
|
||||||
|
private final String RES_TILE = "410.png";
|
||||||
|
private final String RES_DIGIT = "420.png";
|
||||||
|
private final String RES_SMILEY = "430.png";
|
||||||
|
|
||||||
|
private BufferedImage loadImage(String filename) {
|
||||||
|
BufferedImage image;
|
||||||
|
try {
|
||||||
|
image = ImageIO.read(getClass().getResourceAsStream(filename));
|
||||||
|
} catch (Exception e) {
|
||||||
|
JOptionPane.showMessageDialog(null, "Error: Image Loading Failed.");
|
||||||
|
image = null;
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource() {
|
||||||
|
this.digit = this.loadImage(this.RES_DIGIT);
|
||||||
|
this.smiley = this.loadImage(this.RES_SMILEY);
|
||||||
|
this.tile = this.loadImage(this.RES_TILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getDigit() {
|
||||||
|
return this.digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getSmiley() {
|
||||||
|
return this.smiley;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getTile() {
|
||||||
|
return this.tile;
|
||||||
|
}
|
||||||
|
}
|
64
src/Smiley.java
Normal file
64
src/Smiley.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Smiley extends JLabel implements MouseListener {
|
||||||
|
private static final long serialVersionUID = -1028805830774712972L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
private BufferedImage image;
|
||||||
|
|
||||||
|
private final int SIZE = 24;
|
||||||
|
|
||||||
|
public Smiley(Board board) {
|
||||||
|
super("", JLabel.CENTER);
|
||||||
|
this.board = board;
|
||||||
|
this.image = this.board.getMain().getImage().getSmiley();
|
||||||
|
this.setSmileyIcon("smile");
|
||||||
|
addMouseListener(this);
|
||||||
|
setVerticalAlignment(JLabel.CENTER);
|
||||||
|
setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
setPreferredSize(new Dimension(this.SIZE, this.SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int topMargin(String state) {
|
||||||
|
String[] states = {"smile down", "boss", "death", "oops", "smile"};
|
||||||
|
for (int i = 0; i < states.length; i += 1) {
|
||||||
|
if (states[i].equals(state)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmileyIcon(String state) {
|
||||||
|
setIcon(
|
||||||
|
new ImageIcon(
|
||||||
|
this.image.getSubimage(0, this.SIZE * this.topMargin(state), this.SIZE, this.SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||||
|
this.setSmileyIcon("smile down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||||
|
this.setSmileyIcon("smile");
|
||||||
|
this.board.getMain().newGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {}
|
||||||
|
}
|
178
src/Storage.java
Normal file
178
src/Storage.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Storage {
|
||||||
|
private int difficulty;
|
||||||
|
private int height;
|
||||||
|
private int width;
|
||||||
|
private int mines;
|
||||||
|
private boolean creepy;
|
||||||
|
private boolean soundEnabled;
|
||||||
|
private int[] records;
|
||||||
|
private String[] names;
|
||||||
|
|
||||||
|
private final int NUM_OF_DIFFICULTIES = 3;
|
||||||
|
private final String DATA_FILE = "Minesweeper.dat";
|
||||||
|
|
||||||
|
private void open(final String filename) throws FileNotFoundException, IOException {
|
||||||
|
DataInputStream in = new DataInputStream(new FileInputStream(filename));
|
||||||
|
this.difficulty = in.readInt();
|
||||||
|
this.height = in.readInt();
|
||||||
|
this.width = in.readInt();
|
||||||
|
this.mines = in.readInt();
|
||||||
|
this.creepy = in.readBoolean();
|
||||||
|
this.soundEnabled = in.readBoolean();
|
||||||
|
for (int i = 0; i < NUM_OF_DIFFICULTIES; i += 1) {
|
||||||
|
this.records[i] = in.readInt();
|
||||||
|
this.names[i] = in.readUTF();
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Storage() {
|
||||||
|
this.records = new int[this.NUM_OF_DIFFICULTIES];
|
||||||
|
this.names = new String[this.NUM_OF_DIFFICULTIES];
|
||||||
|
try {
|
||||||
|
this.open(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.difficulty = 0;
|
||||||
|
this.height = 9;
|
||||||
|
this.width = 9;
|
||||||
|
this.mines = 10;
|
||||||
|
this.creepy = false;
|
||||||
|
this.soundEnabled = false;
|
||||||
|
this.records = new int[] {999, 999, 999};
|
||||||
|
this.names = new String[] {"Anonymous", "Anonymous", "Anonymous"};
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception v) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(final String filename) throws FileNotFoundException, IOException {
|
||||||
|
DataOutputStream out = new DataOutputStream(new FileOutputStream(filename));
|
||||||
|
out.writeInt(this.difficulty);
|
||||||
|
out.writeInt(this.height);
|
||||||
|
out.writeInt(this.width);
|
||||||
|
out.writeInt(this.mines);
|
||||||
|
out.writeBoolean(this.creepy);
|
||||||
|
out.writeBoolean(this.soundEnabled);
|
||||||
|
for (int i = 0; i < NUM_OF_DIFFICULTIES; i += 1) {
|
||||||
|
out.writeInt(this.records[i]);
|
||||||
|
out.writeUTF(this.names[i]);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDifficulty() {
|
||||||
|
return this.difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return this.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return this.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMines() {
|
||||||
|
return this.mines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreepy() {
|
||||||
|
return this.creepy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSoundEnabled() {
|
||||||
|
return this.soundEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecord(int difficulty) {
|
||||||
|
return this.records[difficulty];
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(int difficulty) {
|
||||||
|
return this.names[difficulty];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDifficulty(int difficulty) {
|
||||||
|
this.difficulty = difficulty;
|
||||||
|
switch (difficulty) {
|
||||||
|
case 0:
|
||||||
|
this.height = 9;
|
||||||
|
this.width = 9;
|
||||||
|
this.mines = 10;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this.height = 16;
|
||||||
|
this.width = 16;
|
||||||
|
this.mines = 40;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.height = 16;
|
||||||
|
this.width = 30;
|
||||||
|
this.mines = 99;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMines(int mines) {
|
||||||
|
this.mines = mines;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void switchCreepy() {
|
||||||
|
this.creepy = !this.creepy;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void switchSound() {
|
||||||
|
this.soundEnabled = !this.soundEnabled;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecord(int difficulty, int score) {
|
||||||
|
this.records[difficulty] = score;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(int difficulty, String name) {
|
||||||
|
this.names[difficulty] = name;
|
||||||
|
try {
|
||||||
|
this.save(this.DATA_FILE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
199
src/Tile.java
Normal file
199
src/Tile.java
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class Tile extends JLabel implements MouseListener {
|
||||||
|
private static final long serialVersionUID = -6873580061751396083L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
private BufferedImage image;
|
||||||
|
|
||||||
|
private boolean uncovered;
|
||||||
|
private boolean flagged;
|
||||||
|
private boolean unsure;
|
||||||
|
private boolean dud;
|
||||||
|
|
||||||
|
private int row;
|
||||||
|
private int col;
|
||||||
|
private int value; // -1~8 (-1: mine)
|
||||||
|
|
||||||
|
private final int SIZE = 16;
|
||||||
|
|
||||||
|
public Tile(int row, int col, Board board) {
|
||||||
|
super("", JLabel.CENTER);
|
||||||
|
this.board = board;
|
||||||
|
this.image = this.board.getMain().getImage().getTile();
|
||||||
|
this.uncovered = false;
|
||||||
|
this.flagged = false;
|
||||||
|
this.unsure = false;
|
||||||
|
this.dud = false;
|
||||||
|
this.row = row;
|
||||||
|
this.col = col;
|
||||||
|
this.setValue(0);
|
||||||
|
this.setTileIcon("covered");
|
||||||
|
addMouseListener(this);
|
||||||
|
setVerticalAlignment(JLabel.CENTER);
|
||||||
|
setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
setPreferredSize(new Dimension(this.SIZE, this.SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int topMargin(String state) {
|
||||||
|
String[] states = {
|
||||||
|
"covered",
|
||||||
|
"flagged",
|
||||||
|
"unsure",
|
||||||
|
"-1",
|
||||||
|
"misflagged",
|
||||||
|
"covered mine",
|
||||||
|
"unsure down",
|
||||||
|
"8",
|
||||||
|
"7",
|
||||||
|
"6",
|
||||||
|
"5",
|
||||||
|
"4",
|
||||||
|
"3",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"0"
|
||||||
|
};
|
||||||
|
for (int i = 0; i < states.length; i += 1) {
|
||||||
|
if (states[i].equals(state)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTileIcon(String state) {
|
||||||
|
setIcon(
|
||||||
|
new ImageIcon(
|
||||||
|
this.image.getSubimage(0, this.SIZE * this.topMargin(state), this.SIZE, this.SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMine() {
|
||||||
|
return (this.value == -1 || this.dud);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUncovered() {
|
||||||
|
return this.uncovered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlagged() {
|
||||||
|
return this.flagged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnsure() {
|
||||||
|
return this.unsure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDud() {
|
||||||
|
return this.dud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMine() {
|
||||||
|
this.value = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDud() {
|
||||||
|
this.dud = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uncover(boolean expanding) {
|
||||||
|
this.uncovered = true;
|
||||||
|
Minesweeper main = this.board.getMain();
|
||||||
|
if (this.value >= 0 || this.isDud()) {
|
||||||
|
if (this.isDud()) {
|
||||||
|
this.setTileIcon("unsure down");
|
||||||
|
} else {
|
||||||
|
this.setTileIcon(String.valueOf(this.value));
|
||||||
|
}
|
||||||
|
if (this.value == 0 && !this.isDud()) {
|
||||||
|
this.board.expand(row, col);
|
||||||
|
}
|
||||||
|
if (main.getStorage().isCreepy()
|
||||||
|
&& !this.isDud()
|
||||||
|
&& !expanding
|
||||||
|
&& Math.round((float) Math.random() * 10) == 0) {
|
||||||
|
main.getPlay().boom();
|
||||||
|
}
|
||||||
|
this.board.checkWon(expanding);
|
||||||
|
} else {
|
||||||
|
this.setTileIcon("-1");
|
||||||
|
main.delGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uncover() {
|
||||||
|
this.uncover(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggleFlagged() {
|
||||||
|
Info info = this.board.getMain().getInfo();
|
||||||
|
if (!this.flagged && !this.unsure) {
|
||||||
|
this.flagged = true;
|
||||||
|
this.setTileIcon("flagged");
|
||||||
|
info.getCounter().decrease();
|
||||||
|
} else if (this.flagged) {
|
||||||
|
this.flagged = false;
|
||||||
|
this.unsure = true;
|
||||||
|
this.setTileIcon("unsure");
|
||||||
|
info.getCounter().increase();
|
||||||
|
} else {
|
||||||
|
this.flagged = false;
|
||||||
|
this.setTileIcon("covered");
|
||||||
|
if (!this.unsure) {
|
||||||
|
info.getCounter().increase();
|
||||||
|
}
|
||||||
|
this.unsure = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
Minesweeper main = this.board.getMain();
|
||||||
|
if (!main.isGameStarted()) {
|
||||||
|
main.startGame();
|
||||||
|
main.getInfo().getTimer().start();
|
||||||
|
if (main.getStorage().isSoundEnabled() && !main.getStorage().isCreepy()) {
|
||||||
|
main.getPlay().tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SwingUtilities.isLeftMouseButton(e) && !this.uncovered && !this.flagged) {
|
||||||
|
this.setTileIcon("0");
|
||||||
|
} else if (SwingUtilities.isMiddleMouseButton(e)) {
|
||||||
|
if (!this.flagged) {
|
||||||
|
this.setTileIcon("0");
|
||||||
|
}
|
||||||
|
main.getInfo().getSmiley().setSmileyIcon("oops");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
this.board.getMain().getInfo().getSmiley().setSmileyIcon("smile");
|
||||||
|
if ((SwingUtilities.isLeftMouseButton(e) || SwingUtilities.isMiddleMouseButton(e))
|
||||||
|
&& !this.flagged) {
|
||||||
|
this.uncover();
|
||||||
|
} else if (SwingUtilities.isRightMouseButton(e) && !this.uncovered) {
|
||||||
|
this.toggleFlagged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {}
|
||||||
|
}
|
83
src/TimerDisplay.java
Normal file
83
src/TimerDisplay.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import java.awt.*;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
|
||||||
|
|
||||||
|
public class TimerDisplay extends JPanel {
|
||||||
|
private static final long serialVersionUID = -1661506846325986431L;
|
||||||
|
|
||||||
|
private Board board;
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
private Digit hundred;
|
||||||
|
private Digit tenth;
|
||||||
|
private Digit first;
|
||||||
|
|
||||||
|
private int seconds;
|
||||||
|
private boolean stopped;
|
||||||
|
|
||||||
|
public TimerDisplay(Board board) {
|
||||||
|
this.board = board;
|
||||||
|
this.hundred = new Digit(this.board);
|
||||||
|
this.tenth = new Digit(this.board);
|
||||||
|
this.first = new Digit(this.board);
|
||||||
|
setBackground(new Color(192, 192, 192));
|
||||||
|
setBorder(
|
||||||
|
BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createEmptyBorder(5, 5, 5, 5),
|
||||||
|
new ButtonBorder(
|
||||||
|
Color.white, Color.white, new Color(128, 128, 128), new Color(128, 128, 128))));
|
||||||
|
setVisible(false);
|
||||||
|
setLayout(new GridLayout(1, 3, 0, 0));
|
||||||
|
removeAll();
|
||||||
|
add(this.hundred);
|
||||||
|
add(this.tenth);
|
||||||
|
add(this.first);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTime() {
|
||||||
|
return this.seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
this.stopped = false;
|
||||||
|
this.timer = new Timer();
|
||||||
|
TimerTask tt =
|
||||||
|
new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
increase();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.timer.scheduleAtFixedRate(tt, 0, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (!this.stopped) {
|
||||||
|
this.timer.cancel();
|
||||||
|
this.stopped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increase() {
|
||||||
|
this.seconds += 1;
|
||||||
|
if (this.seconds >= 999) {
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.seconds = 0;
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDisplay() {
|
||||||
|
this.hundred.setDigitIcon(String.valueOf(seconds / 100));
|
||||||
|
this.tenth.setDigitIcon(String.valueOf(seconds / 10 % 10));
|
||||||
|
this.first.setDigitIcon(String.valueOf(seconds % 10));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user