import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class CleanMine extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
MineButton[][] allButtons;
JButton startButton;
public static JLabel mineRemain;
public static JLabel timeIsUsed;
JMenuBar mainMenuBar;
JLabel text1,text2;
int row,col,mineCount;
JPanel center;
JMenuItem item;
JMenuItem item1;
JMenuItem item2;
JMenuItem item3;
JMenuItem item4;
MyThread thread1;
public CleanMine(){
initMenuBar();
this.setJMenuBar(mainMenuBar);
init();
}
private void init() {
thread1 =new MyThread();
JPanel pane1 =new JPanel();
pane1.add(text1=new JLabel("剩余地雷:"));
pane1.add(mineRemain = new JLabel("10"));
pane1.add(startButton =new JButton("重新开始"));
pane1.add(text2 =new JLabel("用时:"));
pane1.add(timeIsUsed = new JLabel("0"));
startButton.addActionListener(this);
this.add(pane1,BorderLayout.NORTH);
this.row=9;
this.col=9;
this.mineCount=10;
this.setTitle("扫雷");
restart();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thread1.start();
}
private void restart() {
if(center!=null){
this.remove(center);
}
center=new AllButtonPanel(row,col,mineCount);
this.add(center,BorderLayout.CENTER);
mineRemain.setText(mineCount+"");
timeIsUsed.setText("0");
this.setSize(col*30,row*30+10);
this.setResizable(false);
this.setVisible(true);
thread1.setSuspend(false);
}
private void initMenuBar(){
mainMenuBar=new JMenuBar();
JMenu game=new JMenu("游戏");
JMenu help=new JMenu("帮助");
game.add(item=new JMenuItem("开局"));
item.addActionListener(this);
game.addSeparator();
ButtonGroup bg=new ButtonGroup();
game.add(item1=new JCheckBoxMenuItem("初级",true));
game.add(item2=new JCheckBoxMenuItem("中级",false));
game.add(item3=new JCheckBoxMenuItem("高级",false));
game.add(item4=new JCheckBoxMenuItem("自定义...",false));
bg.add(item1);item1.addActionListener(this);
bg.add(item2);item2.addActionListener(this);
bg.add(item3);item3.addActionListener(this);
bg.add(item4);item4.addActionListener(this);
game.addSeparator();
game.add(item=new JMenuItem("退出"));item.addActionListener(this);
help.add(item=new JMenuItem("查看帮助"));item.addActionListener(this);
help.add(item=new JMenuItem("关于扫雷..."));item.addActionListener(this);
mainMenuBar.add(game);
mainMenuBar.add(help);
}
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("初级")){
this.row=9;
this.col=9;
this.mineCount=10;
restart();
}
if(e.getActionCommand().equals("中级")){
this.row=16;
this.col=16;
this.mineCount=40;
restart();
}
if(e.getActionCommand().equals("高级")){
this.row=16;
this.col=30;
this.mineCount=99;
restart();
}
if(e.getActionCommand().equals("重新开始")){
restart();
}
if(e.getActionCommand().equals("退出")){
System.exit(0);
}
}
public static void main(String[] args) {
new CleanMine();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
public class AllButtonPanel extends JPanel implements MouseListener{
private static final long serialVersionUID = -8983741219845014117L;
private int row;//行数
private int col;//列数
private int mineCount;//地雷数
private MineButton[][] allButtons;//所有按钮
private static boolean flag=false;//用来判断是否已经执行双击事件
private static int clickNum=0;//用来判断是否该执行双击事件
public AllButtonPanel(int row,int col,int mineCount){
this.row=row;
this.col=col;
this.mineCount=mineCount;
allButtons=new MineButton[row][col];
createButtons();
createMine();
init();
}
private void init(){
this.setLayout(new GridLayout(row,col));
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
this.add(allButtons[i][j]);
}
}
}
private void createMine(){
int n=0;
while(n<mineCount){//随机生成mineCount个地雷
int i=(int)(Math.random()*row);
int j=(int)(Math.random()*col);
if(!allButtons[i][j].isMine()){
allButtons[i][j].setCountOfSurroundMines(-1);
allButtons[i][j].setIsMine(true);
n++;
}
}
for(int i=0;i<row;i++){//计算每个位置的周围地雷数
for(int j=0;j<col;j++){
if(!allButtons[i][j].isMine()){
allButtons[i][j].setCountOfSurroundMines(getSurroundMineCount(i,j));
}
}
}
}
//统计(i,j)坐标周围8个位置的地雷数
private int getSurroundMineCount(int i,int j){
int num=0;
if(i-1>=0 && j-1>=0){
num+=(allButtons[i-1][j-1].isMine()?1:0);
}
if(i-1>=0){
num+=(allButtons[i-1][j].isMine()?1:0);
}
if(i-1>=0&&j+1<col){
num+=(allButtons[i-1][j+1].isMine()?1:0);
}
if(j-1>=0){
num+=(allButtons[i][j-1].isMine()?1:0);
}
if(j+1<col){
num+=(allButtons[i][j+1].isMine()?1:0);
}
if(i+1<row&&j-1>=0){
num+=(allButtons[i+1][j-1].isMine()?1:0);
}
if(i+1<row){
num+=(allButtons[i+1][j].isMine()?1:0);
}
if(i+1<row&&j+1<col){
num+=(allButtons[i+1][j+1].isMine()?1:0);
}
return num;
}
private void createButtons(){
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
allButtons[i][j]=new MineButton(i,j);
allButtons[i][j].setSize(6,6);
allButtons[i][j].addMouseListener(this);
}
}
}
/**
* 排空方法,若(i,j)位置为空,则显示空白。然后依次递归找它周围的8个位置。
*/
public void showEmpty(int i,int j){
MineButton b=allButtons[i][j];
if(b.isCleaned()){
return;
}
if(b.getCountOfSurroundMines()==0){
b.setBackground(Color.LIGHT_GRAY);
b.setIsCleaned(true);
if(i-1>=0&&j-1>=0){
showEmpty(i-1,j-1);
}
if(i-1>=0){
showEmpty(i-1,j);
}
if(i-1>=0&&j+1<col){
showEmpty(i-1,j+1);
}
if(j-1>=0){
showEmpty(i,j-1);
}
if(j+1<col){
showEmpty(i,j+1);
}
if(i+1<row&&j-1>=0){
showEmpty(i+1,j-1);
}
if(i+1<row){
showEmpty(i+1,j);
}
if(i+1<row&&j+1<col){
showEmpty(i+1,j+1);
}
}else if(b.getCountOfSurroundMines()>0){
b.setText(b.getCountOfSurroundMines()+"");
b.setBackground(Color.LIGHT_GRAY);
b.setIsCleaned(true);
}
}
private void jumpToGameOver() {
for(int i=0;i<allButtons.length;i++){//把所有按钮都显示出来
for(int j=0;j<allButtons[i].length;j++){
if(allButtons[i][j].isMine()){//如果该位置是地雷
allButtons[i][j].setText("@");
}else if(allButtons[i][j].getCountOfSurroundMines()==0){//如果该位置为空 allButtons[i][j].setText("");
allButtons[i][j].setBackground(Color.LIGHT_GRAY);
}else{//如果该位置不是地雷,但周围8个位置中有地雷
allButtons[i][j].setText(allButtons[i][j].getCountOfSurroundMines()+"");
allButtons[i][j].setBackground(Color.LIGHT_GRAY);
}
}
}
CleanMine.mineRemain.setText("0");
}
public void mouseClicked(MouseEvent e){
final MouseEvent me=e;//事件源
flag=false;//每次点击鼠标初始化双击事件执行标志为false
if (clickNum == 1){//当clickNum==1时执行双击事件
this.mouseDoubleClicked(me);//执行双击事件
clickNum=0;//初始化双击事件执行标志为0
flag=true;//双击事件已执行,事件标志为true
return;
}
//定义定时器
java.util.Timer timer=new java.util.Timer();
//定时器开始执行,延时0.2秒后确定是否执行单击事件
timer.schedule(new java.util.TimerTask(){
private int n=0;//记录定时器执行次数
public void run(){
if(flag){//如果双击事件已经执行,那么直接取消单击执行
n=0;
clickNum=0;
this.cancel();
return;
}
if(n == 1){//定时器等待0.2秒后,双击事件仍未发生,执行单击事件
mouseSingleClicked(me);//执行单击事件
flag = true;
clickNum=0;
n=0;
this.cancel();
return;
}
clickNum++;
n++;
}
},new Date(),200);
}
public void mouseSingleClicked(MouseEvent e){
if(e.getButton()==MouseEvent.BUTTON3){
int remain=Integer.parseInt(CleanMine.mineRemain.getText());
JButton b=(JButton)e.getSource();
if(b.getText().equals("")&&
!(CleanMine.mineRemain.getText().trim().equals("0"))){
remain--;
CleanMine.mineRemain.setText(remain+"");
b.setText("&");
}else if(b.getText().equals("&")){
remain++;
CleanMine.mineRemain.setText(remain+"");
b.setText("");
}
}
if(e.getButton()==MouseEvent.BUTTON1){
MineButton b=(MineButton)e.getSource();
int r=b.getRow();
int c=b.getColumn();
if(allButtons[r][c].isMine()){//如果是地雷
jumpToGameOver();
}else{//如果不是地雷
showEmpty(r,c);//执行排空操作
}
}
}
public void mouseDoubleClicked(MouseEvent e){
if(e.getButton() == MouseEvent.BUTTON3){
MineButton b=(MineButton)e.getSource();
int r=b.getRow();
int c=b.getColumn();
if(b.isCleaned()){
if(getCountOfSurroundFlag(r,c) == b.getCountOfSurroundMines()){
showSurroundButton(r,c);
}
}
}
}
private void showSurroundButton(int i, int j){
MineButton b=allButtons[i][j];
if(b.getCountOfSurroundMines()>0){
if(i-1>=0&&j-1>=0){
if(allButtons[i-1][j-1].isMine()&&allButtons[i-1][j-1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i-1,j-1);
}
if(i-1>=0){
if(allButtons[i-1][j].isMine()&&allButtons[i-1][j].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i-1,j);
}
if(i-1>=0&&j+1<col){
if(allButtons[i-1][j+1].isMine()&&allButtons[i-1][j+1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i-1,j+1);
}
if(j-1>=0){
if(allButtons[i][j-1].isMine()&&allButtons[i][j-1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i,j-1);
}
if(j+1<col){
if(allButtons[i][j+1].isMine()&&allButtons[i][j+1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i,j+1);
}
if(i+1<row&&j-1>=0){
if(allButtons[i+1][j-1].isMine()&&allButtons[i+1][j-1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i+1,j-1);
}
if(i+1<row){
if(allButtons[i+1][j].isMine()&&allButtons[i+1][j].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i+1,j);
}
if(i+1<row&&j+1<col){
if(allButtons[i+1][j+1].isMine()&&allButtons[i+1][j+1].getText().equals("")){
jumpToGameOver();
}
else showEmpty(i+1,j+1);
}
}else if(b.isMine()){
jumpToGameOver();
}
}
private int getCountOfSurroundFlag(int i,int j) {
int num=0;
if(i-1>=0 && j-1>=0){
num+=(allButtons[i-1][j-1].getText().equals("&")?1:0);
}
if(i-1>=0){
num+=(allButtons[i-1][j].getText().equals("&")?1:0);
}
if(i-1>=0&&j+1<col){
num+=(allButtons[i-1][j+1].getText().equals("&")?1:0);
}
if(j-1>=0){
num+=(allButtons[i][j-1].getText().equals("&")?1:0);
}
if(j+1<col){
num+=(allButtons[i][j+1].getText().equals("&")?1:0);
}
if(i+1<row&&j-1>=0){
num+=(allButtons[i+1][j-1].getText().equals("&")?1:0);
}
if(i+1<row){
num+=(allButtons[i+1][j].getText().equals("&")?1:0);
}
if(i+1<row&&j+1<col){
num+=(allButtons[i+1][j+1].getText().equals("&")?1:0);
}
return num;
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
import java.awt.Insets;
import javax.swing.JButton;
public class MineButton extends JButton {
private int row;
private int col;
private int countOfSurroundMines;
private boolean isMine = false;
private boolean isCleaned = false;
private static final long serialVersionUID = 1L;
public MineButton(int row,int col){
this.row = row;
this.col = col;
this.setSize(6, 6);
this.setMargin(new Insets(0,0,0,0));
}
public int getRow(){
return this.row;
}
public int getColumn(){
return this.col;
}
public int getCountOfSurroundMines(){
return this.countOfSurroundMines;
}
public boolean isMine(){
return this.isMine;
}
public boolean isCleaned(){
return this.isCleaned;
}
public void setRow(int row){
this.row = row;
};
public void setColumn(int col){
this.col = col;
};
public void setCountOfSurroundMines(int cout){
this.countOfSurroundMines = cout;
};
public void setIsCleaned(boolean isCleaned){
this.isCleaned = isCleaned;
};
public void setIsMine(boolean isMine){
this.isMine = isMine;
}
}
public class MyThread extends Thread {
private boolean suspend = false;
private String control = ""; //只是需要一个对象而已,这个对象没有实际意义
public void setSuspend(boolean suspend) {
if(!suspend) {
synchronized(control) {
control.notifyAll();
}
}
this.suspend = suspend;
}
public boolean isSuspend() {
return this.suspend;
}
public void run() {
while(true) {
synchronized(control) {
suspend =Integer.parseInt(CleanMine.mineRemain.getText().trim())<=0;
if(suspend) {
try {
control.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
CleanMine.timeIsUsed.setText((Integer.parseInt(CleanMine.timeIsUsed.getText())+1)+"");
}
}
}
}
}
4个class文件。