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文件。