查看完整版本: [已解決]MouseEVent的問題,拜託高手們幫忙看看
頁: [1]

z810520 發表於 2019-6-5 06:30 PM

[已解決]MouseEVent的問題,拜託高手們幫忙看看

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

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



import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class NewMineSweeperOnSwing {
   
    private static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("MineSweeper");//大標題
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.setVisible(true);
        JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        
        int h = 10, w = 10, m = 10;
        Board board = new Board(h, w, m);
        
        JPanel top = new JPanel();
        top.add(board.jl);
        frame.add(top);
        
        JPanel field = new JPanel();
        field.setLayout(new GridLayout(h, w));
        
        for(int i = 0; i < h; i++){//setting field
            for(int j = 0; j < w; j++){
                board.getBlock(i,j).addMouseListener(new sweep2(board, i, j));
               
                field.add(board.getBlock(i,j));
            }
        }
        
        for(int i = 0; i < m; i++){//setting mines
            int x = (int)(Math.random()*h);
            int y = (int)(Math.random()*m);
            if(board.getBlock(x,y).getNumber() != -1){
                board.getBlock(x,y).setNumber(-1);
                System.out.print(" "+x+y);//take out later
            }
            else i--;
        }
        
        for(int i = 0; i < h; i++){//setting number of mines
            for(int j = 0; j < w; j++){
                if(board.getBlock(i,j).getNumber() != -1){
                    int n = 0;
                    for(int x = Math.max(0, i-1); x < Math.min(h,i+2); x++){
                        for(int y = Math.max(0, j-1); y < Math.min(w,j+2); y++){
                            if(((i != x) || (j != y)) && board.getBlock(x,y).getNumber() == -1) n++;
                        }
                    }
                    board.getBlock(i,j).setNumber(n);
                }
            }
        }
        
        p.add(top, BorderLayout.NORTH);
        p.add(field, BorderLayout.CENTER);
        frame.setContentPane(p);
    }

    public static void main(String[] args) {
        //GUI
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

@SuppressWarnings("serial") class Block extends JButton{
    private int number;//0~8 for number of mines around, -1 for mine
    private int status;//0 for covered, 1 for flagged, 2 for uncovered
   
    Block(){}//int = 0 by default
   
    public int getNumber(){return number;}
    public int getStatus(){return status;}
    public void setNumber(int n){number = n;}
    public void setStatus(int s){status = s;}
}

class Board{
    private Block[][] b;// all the blocks
    private int h, w, m, bl, r;//height, width, mines, blocks left, result : 0 for not finished, 1 for win, 2 for lose
    public JLabel jl;//label on top showing number of mines left
   
    Board(){}
    Board(int height, int width, int mines){
        h = height;
        w = width;
        m = mines;
        bl = h * w - m;
        b = new Block;
        jl = new JLabel(""+m);
        
        for(int i = 0; i < h; i++){//setting board
            for(int j = 0; j < w; j++){
                b = new Block();
            }
        }
    }
   
    public int getHeight(){return h;}
    public int getWidth(){return w;}
    public int getMines(){return m;}
    public int getBlocksLeft(){return bl;}
    public Block[][] getBlock(){return b;}
    public Block getBlock(int i, int j){return b;}
    public int getResult(){return r;}
    public void setBlocksLeft(int n){bl = n;}
    public void setResult(int i){r = i;}
}

class sweep implements MouseListener{
    sweep(){}
   
    public void mouseClicked(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
   
}

class sweep2 extends sweep{
    int h, w, x, y;
    Board board;
    Block[][] b;
    JLabel l;
   
    sweep2(){}
    sweep2(Board board, int i, int j){
        x = i;
        y = j;
        this.board = board;
        b = board.getBlock();
        h = b.length;
        w = b.length;
        l = board.jl;
    }
   
    @Override public void mouseClicked(MouseEvent e) {
        
        if(board.getResult() == 0){//games not finished
        
            if (e.getButton() != MouseEvent.BUTTON3 && b.getStatus() == 0) {//left click on normal block(autoclick???)
                if(b.getNumber() != -1){//not bomb
                    b.setStatus(2);
                    b.setBackground(Color.WHITE);
                    board.setBlocksLeft(board.getBlocksLeft() - 1);
                    
                    if(b.getNumber() == 0){//click all blocks around if they are not mines
                        for(int i = Math.max(0, x-1); i < Math.min(h,x+2); i++){
                            for(int j = Math.max(0, y-1); j < Math.min(w,y+2); j++){
                                if((i != x) || (j != y)) b.doClick();
                            }
                        }
                    }
                    else//show number of mines around
                        b.setText(""+b.getNumber());
                }
               
                else{//is bomb
                    b.setText("B");
                    b.setBackground(Color.RED);
                    l.setText("(XP)");
                    board.setResult(2);
                }
            
                if(board.getBlocksLeft() == 0){
                    l.setText("(:D)");
                    board.setResult(1);
                }
            }
            
            else if (e.getButton() == MouseEvent.BUTTON3) {//right click
                if(b.getStatus() == 0){
                    b.setStatus(1);
                    b.setText("F");
                    int t = Integer.parseInt(l.getText());
                    l.setText(t-1+"");
                }
                else if(b.getStatus() == 1){
                    b.setStatus(0);
                    b.setText("");
                    int t = Integer.parseInt(l.getText());
                    l.setText(t+1+"");
                }
            }
        }
    }
}



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

補充內容 (2019-6-13 08:56 AM):
已自行解決,只要new個新物件就好了...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>
頁: [1]