伊莉討論區

標題: [已解決]MouseEVent的問題,拜託高手們幫忙看看 [打印本頁]

作者: z810520    時間: 2019-6-5 06:30 PM     標題: [已解決]MouseEVent的問題,拜託高手們幫忙看看

本帖最後由 z810520 於 2019-6-13 08:56 AM 編輯

小弟是Java新手,正在試著寫一個踩地雷的程式,裡面用到Swing跟MouseListener。
我希望當我按的按鈕的周圍沒有地雷時程式能夠自動把周圍也踩過,但我用的DoClick()無法如我預期的運作,我上網查了相關資料,但還是沒看出問題點,還請各位幫忙,謝謝。

  1. import java.awt.event.*;
  2. import java.awt.*;
  3. import javax.swing.*;

  4. public class NewMineSweeperOnSwing {
  5.    
  6.     private static void createAndShowGUI() {
  7.         JFrame.setDefaultLookAndFeelDecorated(true);
  8.         JFrame frame = new JFrame("MineSweeper");//大標題
  9.         frame.setSize(500,500);
  10.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  11.         
  12.         frame.setVisible(true);
  13.         JPanel p = new JPanel();
  14.         p.setLayout(new BorderLayout());
  15.         
  16.         int h = 10, w = 10, m = 10;
  17.         Board board = new Board(h, w, m);
  18.         
  19.         JPanel top = new JPanel();
  20.         top.add(board.jl);
  21.         frame.add(top);
  22.         
  23.         JPanel field = new JPanel();
  24.         field.setLayout(new GridLayout(h, w));
  25.         
  26.         for(int i = 0; i < h; i++){//setting field
  27.             for(int j = 0; j < w; j++){
  28.                 board.getBlock(i,j).addMouseListener(new sweep2(board, i, j));
  29.                
  30.                 field.add(board.getBlock(i,j));
  31.             }
  32.         }
  33.         
  34.         for(int i = 0; i < m; i++){//setting mines
  35.             int x = (int)(Math.random()*h);
  36.             int y = (int)(Math.random()*m);
  37.             if(board.getBlock(x,y).getNumber() != -1){
  38.                 board.getBlock(x,y).setNumber(-1);
  39.                 System.out.print(" "+x+y);//take out later
  40.             }
  41.             else i--;
  42.         }
  43.         
  44.         for(int i = 0; i < h; i++){//setting number of mines
  45.             for(int j = 0; j < w; j++){
  46.                 if(board.getBlock(i,j).getNumber() != -1){
  47.                     int n = 0;
  48.                     for(int x = Math.max(0, i-1); x < Math.min(h,i+2); x++){
  49.                         for(int y = Math.max(0, j-1); y < Math.min(w,j+2); y++){
  50.                             if(((i != x) || (j != y)) && board.getBlock(x,y).getNumber() == -1) n++;
  51.                         }
  52.                     }
  53.                     board.getBlock(i,j).setNumber(n);
  54.                 }
  55.             }
  56.         }
  57.         
  58.         p.add(top, BorderLayout.NORTH);
  59.         p.add(field, BorderLayout.CENTER);
  60.         frame.setContentPane(p);
  61.     }

  62.     public static void main(String[] args) {
  63.         //GUI
  64.         javax.swing.SwingUtilities.invokeLater(new Runnable() {
  65.             public void run() {
  66.                 createAndShowGUI();
  67.             }
  68.         });
  69.     }
  70. }

  71. @SuppressWarnings("serial") class Block extends JButton{
  72.     private int number;//0~8 for number of mines around, -1 for mine
  73.     private int status;//0 for covered, 1 for flagged, 2 for uncovered
  74.    
  75.     Block(){}//int = 0 by default
  76.    
  77.     public int getNumber(){return number;}
  78.     public int getStatus(){return status;}
  79.     public void setNumber(int n){number = n;}
  80.     public void setStatus(int s){status = s;}
  81. }

  82. class Board{
  83.     private Block[][] b;// all the blocks
  84.     private int h, w, m, bl, r;//height, width, mines, blocks left, result : 0 for not finished, 1 for win, 2 for lose
  85.     public JLabel jl;//label on top showing number of mines left
  86.    
  87.     Board(){}
  88.     Board(int height, int width, int mines){
  89.         h = height;
  90.         w = width;
  91.         m = mines;
  92.         bl = h * w - m;
  93.         b = new Block[h][w];
  94.         jl = new JLabel(""+m);
  95.         
  96.         for(int i = 0; i < h; i++){//setting board
  97.             for(int j = 0; j < w; j++){
  98.                 b[i][j] = new Block();
  99.             }
  100.         }
  101.     }
  102.    
  103.     public int getHeight(){return h;}
  104.     public int getWidth(){return w;}
  105.     public int getMines(){return m;}
  106.     public int getBlocksLeft(){return bl;}
  107.     public Block[][] getBlock(){return b;}
  108.     public Block getBlock(int i, int j){return b[i][j];}
  109.     public int getResult(){return r;}
  110.     public void setBlocksLeft(int n){bl = n;}
  111.     public void setResult(int i){r = i;}
  112. }

  113. class sweep implements MouseListener{
  114.     sweep(){}
  115.    
  116.     public void mouseClicked(MouseEvent e){}
  117.     public void mouseEntered(MouseEvent e){}
  118.     public void mouseExited(MouseEvent e){}
  119.     public void mousePressed(MouseEvent e){}
  120.     public void mouseReleased(MouseEvent e){}
  121.    
  122. }

  123. class sweep2 extends sweep{
  124.     int h, w, x, y;
  125.     Board board;
  126.     Block[][] b;
  127.     JLabel l;
  128.    
  129.     sweep2(){}
  130.     sweep2(Board board, int i, int j){
  131.         x = i;
  132.         y = j;
  133.         this.board = board;
  134.         b = board.getBlock();
  135.         h = b.length;
  136.         w = b[0].length;
  137.         l = board.jl;
  138.     }
  139.    
  140.     @Override public void mouseClicked(MouseEvent e) {
  141.         
  142.         if(board.getResult() == 0){//games not finished
  143.         
  144.             if (e.getButton() != MouseEvent.BUTTON3 && b[x][y].getStatus() == 0) {//left click on normal block(autoclick???)
  145.                 if(b[x][y].getNumber() != -1){//not bomb
  146.                     b[x][y].setStatus(2);
  147.                     b[x][y].setBackground(Color.WHITE);
  148.                     board.setBlocksLeft(board.getBlocksLeft() - 1);
  149.                     
  150.                     if(b[x][y].getNumber() == 0){//click all blocks around if they are not mines
  151.                         for(int i = Math.max(0, x-1); i < Math.min(h,x+2); i++){
  152.                             for(int j = Math.max(0, y-1); j < Math.min(w,y+2); j++){
  153.                                 if((i != x) || (j != y)) b[i][j].doClick();
  154.                             }
  155.                         }
  156.                     }
  157.                     else//show number of mines around
  158.                         b[x][y].setText(""+b[x][y].getNumber());
  159.                 }
  160.                
  161.                 else{//is bomb
  162.                     b[x][y].setText("B");
  163.                     b[x][y].setBackground(Color.RED);
  164.                     l.setText("(XP)");
  165.                     board.setResult(2);
  166.                 }
  167.             
  168.                 if(board.getBlocksLeft() == 0){
  169.                     l.setText("(:D)");
  170.                     board.setResult(1);
  171.                 }
  172.             }
  173.             
  174.             else if (e.getButton() == MouseEvent.BUTTON3) {//right click
  175.                 if(b[x][y].getStatus() == 0){
  176.                     b[x][y].setStatus(1);
  177.                     b[x][y].setText("F");
  178.                     int t = Integer.parseInt(l.getText());
  179.                     l.setText(t-1+"");
  180.                 }
  181.                 else if(b[x][y].getStatus() == 1){
  182.                     b[x][y].setStatus(0);
  183.                     b[x][y].setText("");
  184.                     int t = Integer.parseInt(l.getText());
  185.                     l.setText(t+1+"");
  186.                 }
  187.             }
  188.         }
  189.     }
  190. }
複製代碼


補充內容 (2019-6-6 10:06 AM):
目前看來是doClick()無法觸發mouseListener,但我的程式會用到左鍵跟右鍵,所以不能用actionListener,有什麼建議嗎?

補充內容 (2019-6-13 08:56 AM):
已自行解決,只要new個新物件就好了




歡迎光臨 伊莉討論區 (http://a04.eyny.com/) Powered by Discuz!