I made this minesweeper game earlier this summer. It shows many things, including:
array use,
1D array to 2D array,
gridlayout,
changing the way a JButton works depending on mouse button used,
floodfill,
loops,
GUI.

slightly long, 382 lines, can probably be condensed.

There is one known bug that i cannot seem to fix: when a floodfill causes a win, and the OK button is clicked on the win dialog, it will automatically click a button on the new game, not a problem usually, but in games that are set to be large with a small amount of bombs, it can cause an infinite loop :( , if you see a fix please comment or PM me, thanks.

have fun.

import java.awt.* ;
import java.awt.event.* ;
import java.awt.geom.* ;
import javax.swing.* ;
import javax.swing.event.* ;
/**MineSweeper by SciWizEH*/
public class MineSweeper extends JFrame implements ActionListener ,
		MouseListener {
	int rows = 10 ;
	int cols = 10 ;
	int numMines = 10 ;
	GridLayout layout = new GridLayout ( rows , cols ) ;
	/*type[][] name = new type[rows][cols];
	 * type[x][y];
	 * is 1d
	 * type[] name = new type[rows*cols];
	 * type[(rows*y)+x];*/
	boolean [ ] mines = new boolean [ rows * cols ] ;
	boolean [ ] clickable = new boolean [ rows * cols ] ;
	boolean lost = false ;
	boolean won = false ;
	int [ ] numbers = new int [ rows * cols ] ;
	JButton [ ] buttons = new JButton [ rows * cols ] ;
	boolean [ ] clickdone = new boolean [ rows * cols ] ;
	JMenuItem newGameButton = new JMenuItem ( "new game" ) ;
	JMenuItem difficulty = new JMenuItem ( "options" ) ;
	JLabel mineLabel = new JLabel ( "mines: " + numMines + " marked: 0" ) ;
	JPanel p = new JPanel ( ) ;

	public MineSweeper ( ) {
		p.setLayout ( layout ) ;
		setupI ( ) ;
		for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
			p.add ( buttons [ i ] ) ;
		}
		JMenuBar mb = new JMenuBar ( ) ;
		JMenu m = new JMenu ( "file" ) ;
		newGameButton.addActionListener ( this ) ;
		m.add ( newGameButton ) ;
		difficulty.addActionListener ( this ) ;
		m.add ( difficulty ) ;
		mb.add ( m ) ;
		this.setJMenuBar ( mb ) ;
		this.add ( p ) ;
		this.add ( mineLabel , BorderLayout.SOUTH ) ;
		this.pack ( ) ;
		this.setVisible ( true ) ;
	}

	public void fillMines ( ) {
		int needed = numMines ;
		while ( needed > 0 ) {
			int x = ( int ) Math.floor ( Math.random ( ) * rows ) ;
			int y = ( int ) Math.floor ( Math.random ( ) * cols ) ;
			if ( ! mines [ ( rows * y ) + x ] ) {
				mines [ ( rows * y ) + x ] = true ;
				needed -- ;
			}
		}
	}

	public void fillNumbers ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				int cur = ( rows * y ) + x ;
				if ( mines [ cur ] ) {
					numbers [ cur ] = 0 ;
					continue ;
				}
				int temp = 0 ;
				boolean l = ( x - 1 ) >= 0 ;
				boolean r = ( x + 1 ) < rows ;
				boolean u = ( y - 1 ) >= 0 ;
				boolean d = ( y + 1 ) < cols ;
				int left = ( rows * ( y ) ) + ( x - 1 ) ;
				int right = ( rows * ( y ) ) + ( x + 1 ) ;
				int up = ( rows * ( y - 1 ) ) + ( x ) ;
				int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
				int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
				int down = ( rows * ( y + 1 ) ) + ( x ) ;
				int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
				int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;
				if ( u ) {
					if ( mines [ up ] ) {
						temp ++ ;
					}
					if ( l ) {
						if ( mines [ upleft ] ) {
							temp ++ ;
						}
					}
					if ( r ) {
						if ( mines [ upright ] ) {
							temp ++ ;
						}
					}
				}
				if ( d ) {
					if ( mines [ down ] ) {
						temp ++ ;
					}
					if ( l ) {
						if ( mines [ downleft ] ) {
							temp ++ ;
						}
					}
					if ( r ) {
						if ( mines [ downright ] ) {
							temp ++ ;
						}
					}
				}
				if ( l ) {
					if ( mines [ left ] ) {
						temp ++ ;
					}
				}
				if ( r ) {
					if ( mines [ right ] ) {
						temp ++ ;
					}
				}
				numbers [ cur ] = temp ;
			}
		}
	}

	public void setupI ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				mines [ ( rows * y ) + x ] = false ;
				clickdone [ ( rows * y ) + x ] = false ;
				clickable [ ( rows * y ) + x ] = true ;
				buttons [ ( rows * y ) + x ] = new JButton ( /*"" + ( x * y )*/) ;
				buttons [ ( rows * y ) + x ].setPreferredSize ( new Dimension (
						45 , 45 ) ) ;
				buttons [ ( rows * y ) + x ].addActionListener ( this ) ;
				buttons [ ( rows * y ) + x ].addMouseListener ( this ) ;
			}
		}
		fillMines ( ) ;
		fillNumbers ( ) ;
	}

	public void setupI2 ( ) {
		this.remove ( p ) ;
		p = new JPanel ( ) ;
		layout = new GridLayout ( rows , cols ) ;
		p.setLayout ( layout ) ;
		buttons = new JButton [ rows * cols ] ;
		mines = new boolean [ rows * cols ] ;
		clickdone = new boolean [ rows * cols ] ;
		clickable = new boolean [ rows * cols ] ;
		numbers = new int [ rows * cols ] ;
		setupI ( ) ;
		for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
			p.add ( buttons [ i ] ) ;
		}
		this.add ( p ) ;
		this.pack ( ) ;
		fillMines ( ) ;
		fillNumbers ( ) ;
	}

	public void setup ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				mines [ ( rows * y ) + x ] = false ;
				clickdone [ ( rows * y ) + x ] = false ;
				clickable [ ( rows * y ) + x ] = true ;
				buttons [ ( rows * y ) + x ].setEnabled ( true ) ;
				buttons [ ( rows * y ) + x ].setText ( "" ) ;
			}
		}
		fillMines ( ) ;
		fillNumbers ( ) ;
		lost = false ;
		mineLabel.setText ( "mines: " + numMines + " marked: 0" ) ;
	}

	public static void main ( String [ ] args ) {
		new MineSweeper ( ) ;
	}

	public void actionPerformed ( ActionEvent e ) {
		if ( e.getSource ( ) == difficulty ) {
			rows = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
					this , "Rows" , "Rows" , JOptionPane.PLAIN_MESSAGE , null ,
					null , 10 ) ) ;
			cols = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
					this , "Columns" , "Columns" , JOptionPane.PLAIN_MESSAGE ,
					null , null , 10 ) ) ;
			numMines = Integer.parseInt ( ( String ) JOptionPane
					.showInputDialog ( this , "Mines" , "Mines" ,
							JOptionPane.PLAIN_MESSAGE , null , null , 10 ) ) ;
			setupI2 ( ) ;
		}
		if ( ! won ) {
			for ( int x = 0 ; x < rows ; x ++ ) {
				for ( int y = 0 ; y < cols ; y ++ ) {
					if ( e.getSource ( ) == buttons [ ( rows * y ) + x ]
							&& ! won && clickable [ ( rows * y ) + x ] ) {
						doCheck ( x , y ) ;
						break ;
					}
				}
			}
		}
		if ( e.getSource ( ) == newGameButton ) {
			setup ( ) ;
			won = false ;
			return ;

		}
		checkWin ( ) ;
	}

	public void mouseEntered ( MouseEvent e ) {

	}

	public void mouseExited ( MouseEvent e ) {

	}

	public void mousePressed ( MouseEvent e ) {
		if ( e.getButton ( ) == 3 ) {
			int n = 0 ;
			for ( int x = 0 ; x < rows ; x ++ ) {
				for ( int y = 0 ; y < cols ; y ++ ) {
					if ( e.getSource ( ) == buttons [ ( rows * y ) + x ] ) {
						clickable [ ( rows * y ) + x ] = ! clickable [ ( rows * y )
								+ x ] ;
					}
					if ( ! clickdone [ ( rows * y ) + x ] ) {
						if ( ! clickable [ ( rows * y ) + x ] ) {
							buttons [ ( rows * y ) + x ].setText ( "X" ) ;
							n ++ ;
						} else {
							buttons [ ( rows * y ) + x ].setText ( "" ) ;
						}
						mineLabel.setText ( "mines: " + numMines + " marked: "
								+ n ) ;
					}
				}
			}
		}
	}

	public void mouseReleased ( MouseEvent e ) {

	}

	public void mouseClicked ( MouseEvent e ) {

	}

	public void doCheck ( int x , int y ) {
		int cur = ( rows * y ) + x ;
		boolean l = ( x - 1 ) >= 0 ;
		boolean r = ( x + 1 ) < rows ;
		boolean u = ( y - 1 ) >= 0 ;
		boolean d = ( y + 1 ) < cols ;
		int left = ( rows * ( y ) ) + ( x - 1 ) ;
		int right = ( rows * ( y ) ) + ( x + 1 ) ;
		int up = ( rows * ( y - 1 ) ) + ( x ) ;
		int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
		int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
		int down = ( rows * ( y + 1 ) ) + ( x ) ;
		int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
		int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

		clickdone [ cur ] = true ;
		buttons [ cur ].setEnabled ( false ) ;
		if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && ! won ) {
			if ( u && ! won ) {
				if ( ! clickdone [ up ] && ! mines [ up ] ) {
					clickdone [ up ] = true ;
					buttons [ up ].doClick ( ) ;
				}
				if ( l && ! won ) {
					if ( ! clickdone [ upleft ] && numbers [ upleft ] != 0
							&& ! mines [ upleft ] ) {
						clickdone [ upleft ] = true ;
						buttons [ upleft ].doClick ( ) ;
					}
				}
				if ( r && ! won ) {
					if ( ! clickdone [ upright ] && numbers [ upright ] != 0
							&& ! mines [ upright ] ) {
						clickdone [ upright ] = true ;
						buttons [ upright ].doClick ( ) ;
					}
				}
			}
			if ( d && ! won ) {
				if ( ! clickdone [ down ] && ! mines [ down ] ) {
					clickdone [ down ] = true ;
					buttons [ down ].doClick ( ) ;
				}
				if ( l && ! won ) {
					if ( ! clickdone [ downleft ] && numbers [ downleft ] != 0
							&& ! mines [ downleft ] ) {
						clickdone [ downleft ] = true ;
						buttons [ downleft ].doClick ( ) ;
					}
				}
				if ( r && ! won ) {
					if ( ! clickdone [ downright ]
							&& numbers [ downright ] != 0
							&& ! mines [ downright ] ) {
						clickdone [ downright ] = true ;
						buttons [ downright ].doClick ( ) ;
					}
				}
			}
			if ( l && ! won ) {
				if ( ! clickdone [ left ] && ! mines [ left ] ) {
					clickdone [ left ] = true ;
					buttons [ left ].doClick ( ) ;
				}
			}
			if ( r && ! won ) {
				if ( ! clickdone [ right ] && ! mines [ right ] ) {
					clickdone [ right ] = true ;
					buttons [ right ].doClick ( ) ;
				}
			}
		} else {
			buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
			if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
				buttons [ cur ].setText ( "" ) ;
			}
		}
		if ( mines [ cur ] && ! won ) {
			buttons [ cur ].setText ( "0" ) ;
			doLose ( ) ;
		}
	}

	public void checkWin ( ) {
		for ( int x = 0 ; x < rows ; x ++ ) {
			for ( int y = 0 ; y < cols ; y ++ ) {
				int cur = ( rows * y ) + x ;
				if ( ! clickdone [ cur ] ) {
					if ( mines [ cur ] ) {
						continue ;
					} else {
						return ;
					}
				}
			}
		}

		doWin ( ) ;
	}

	public void doWin ( ) {
		if ( ! lost && ! won ) {
			won = true ;
			JOptionPane.showMessageDialog ( null ,
					"you win!\nstarting a new game" , "you lose" ,
					JOptionPane.INFORMATION_MESSAGE ) ;
			newGameButton.doClick ( ) ;
		}
	}

	public void doLose ( ) {
		if ( ! lost && ! won ) {
			lost = true ;
			for ( int i = 0 ; i < rows * cols ; i ++ ) {
				if ( ! clickdone [ i ] ) {
					buttons [ i ].doClick ( 0 ) ;
				}
			}
			JOptionPane.showMessageDialog ( null ,
					"you lose!\nstarting a new game" , "you lose" ,
					JOptionPane.ERROR_MESSAGE ) ;
			setup ( ) ;
		}
	}
}

is this code running? I can't find a right code for ordinary minesweeper code in Joption!!! plz help me!!! this is my e-mail <EMAIL SNIPPED>, pls email me!!!

Edited 6 Years Ago by peter_budo: Keep It On The Site - Do not post asking for an answer to be sent to you via email or PM.

how can I fix the errors of your minesweeper in the Jcreator 4.50 ??

how can I fix the errors of your minesweeper in the Jcreator 4.50 ??

I never used JCreater, I wrote this without code completion in BlueJ, it should compile. what errors are you getting?

Uhmm okay SO I FOUND A BUG! I changed the setting of the game to:

ROWS: 10
COLUMNS: 10
MINES: 1
(for fun :P)
The first two times it worked!

After you play it like the 4th time, the game starts to play by itself. So even if I don't click a location, the game automatically picks one and reveals the answer and a JWindow pops up saying "you win" and when you click ok to the new game, it again starts to play by itself. (AGAIN I NEVER CLICKED A LOCATION!) I'm not sure if the code was programmed to do this...
One thing- when this happens on my mac, the tiles are differently colored. Previously the tiles would be grayish black when I click it and it reveals the empty spaces around it, however when the computer plays by itself: the tiles are a vanilla/ white pearlish color.

Uhmm okay SO I FOUND A BUG! I changed the setting of the game to:

ROWS: 10
COLUMNS: 10
MINES: 1
(for fun :P)
The first two times it worked!

After you play it like the 4th time, the game starts to play by itself. So even if I don't click a location, the game automatically picks one and reveals the answer and a JWindow pops up saying "you win" and when you click ok to the new game, it again starts to play by itself. (AGAIN I NEVER CLICKED A LOCATION!) I'm not sure if the code was programmed to do this...
One thing- when this happens on my mac, the tiles are differently colored. Previously the tiles would be grayish black when I click it and it reveals the empty spaces around it, however when the computer plays by itself: the tiles are a vanilla/ white pearlish color.

this is a known issue, see the OP, last paragraph describes the exact issue your having, I have been unable to find a fix

It seems dangerous to have both an action listener and a mouse listener for the same button(s). I don't think there is any guarantee about the order in which these two listeners will be called, especially if there's a lot going on. Maybe the bug is caused by the action listener being executed before the mousePressed ???

That may be true. But I dont believe the mouse listener code would interfere with the action listener code. Worth testing I suppose.

within the action listener doClick() is called on a number of other buttons, in a basic implementation of recursive floodfill.
the problem is that one of the doClick's happens after the win dialog is shown, and new game started, it's a bug in the action listener itself I believe, but I couldn't decide how to floodfill without using doClick() to prevent the problem.
the mouseListener only does something if it's a right click, where an action listener on a button is strictly left click (as far as I'm aware). So they should not be interacting.

 int temp = 0 ;
            boolean l = ( x - 1 ) >= 0 ;
            boolean r = ( x + 1 ) < rows ;
            boolean u = ( y - 1 ) >= 0 ;
            boolean d = ( y + 1 ) < cols ;
            int left = ( rows * ( y ) ) + ( x - 1 ) ;
            int right = ( rows * ( y ) ) + ( x + 1 ) ;
            int up = ( rows * ( y - 1 ) ) + ( x ) ;
            int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
            int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
            int down = ( rows * ( y + 1 ) ) + ( x ) ;
            int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
            int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

            what does this code above do>?

Defines 13 variables and assigns them values.

To be more specific it gets the indices of the buttons to the direction of the current button, the index of a button is it's y coordinate multiplied by rows plus the x (this is actually a misnmer it should be multiplied by the columns but I wasn't thinking when i initially wrote the code)

if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && 
        ! won ) {
            if ( u && ! won ) {
                if ( ! clickdone [ up ] && ! mines [ up ] ) {
                    clickdone [ up ] = true ;
                    buttons [ up ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ upleft ] && numbers [ upleft 
                    ] != 0
                    && ! mines [ upleft ] ) {
                        clickdone [ upleft ] = true ;
                        buttons [ upleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ upright ] && numbers [ 
                        upright ] != 0
                    && ! mines [ upright ] ) {
                        clickdone [ upright ] = true ;
                        buttons [ upright ].doClick ( ) ;
                    }
                }
            }
            if ( d && ! won ) {
                if ( ! clickdone [ down ] && ! mines [ down ] ) {
                    clickdone [ down ] = true ;
                    buttons [ down ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ downleft ] && numbers 
                    [ downleft ] != 0
                    && ! mines [ downleft ] ) {
                        clickdone [ downleft ] = true ;
                        buttons [ downleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ downright ]
                    && numbers [ downright ] != 0
                    && ! mines [ downright ] ) {
                        clickdone [ downright ] = true ;
                        buttons [ downright ].doClick ( ) ;
                    }
                }
            }
            if ( l && ! won ) {
                if ( ! clickdone [ left ] && ! mines [ left ] ) {
                    clickdone [ left ] = true ;
                    buttons [ left ].doClick ( ) ;
                }
            }
            if ( r && ! won ) {
                if ( ! clickdone [ right ] && ! mines [ right ] ) {
                    clickdone [ right ] = true ;
                    buttons [ right ].doClick ( ) ;
                }
            }
        } else {
            buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
            if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
                buttons [ cur ].setText ( "" ) ;
            }
        }
        if ( mines [ cur ] && ! won ) {
            buttons [ cur ].setText ( "0" ) ;
            Lose ( ) ;
        }
    }


all thats confusing whaT DOES IT DO

Adding a timer would require a new thread a new label, and an addition to the win/loose conditions.

The code you quoted above is the code that checks what the box the user clicked on, and if it's a 0 number it clicks the squares around that box in a recursive way, leading to a filling algorithm.

I've altered the code slightly this adds a timer to the bottom I'll leave it to you to find the differences.

import java.awt.* ;
import java.awt.event.* ;
import java.awt.geom.* ;
import javax.swing.* ;
import javax.swing.event.* ;
import javax.swing.Timer;
/**MineSweeper by SciWizEH*/
public class MineSweeper extends JFrame implements ActionListener ,
        MouseListener {
    int rows = 10 ;
    int cols = 10 ;
    int numMines = 10 ;
    GridLayout layout = new GridLayout ( rows , cols ) ;
    /*type[][] name = new type[rows][cols];
     * type[x][y];
     * is 1d
     * type[] name = new type[rows*cols];
     * type[(rows*y)+x];*/
    boolean [ ] mines = new boolean [ rows * cols ] ;
    boolean [ ] clickable = new boolean [ rows * cols ] ;
    boolean lost = false ;
    boolean won = false ;
    int [ ] numbers = new int [ rows * cols ] ;
    JButton [ ] buttons = new JButton [ rows * cols ] ;
    boolean [ ] clickdone = new boolean [ rows * cols ] ;
    JMenuItem newGameButton = new JMenuItem ( "new game" ) ;
    JMenuItem difficulty = new JMenuItem ( "options" ) ;
    JLabel mineLabel = new JLabel ( "mines: " + numMines + " marked: 0" ) ;
    JPanel p = new JPanel ( ) ;
    long startTime;
    int flags = 0;
    Timer timer;
    public MineSweeper ( ) {
        p.setLayout ( layout ) ;
        setupI ( ) ;
        for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
            p.add ( buttons [ i ] ) ;
        }
        timer = new Timer(50,this);
        JMenuBar mb = new JMenuBar ( ) ;
        JMenu m = new JMenu ( "file" ) ;
        newGameButton.addActionListener ( this ) ;
        m.add ( newGameButton ) ;
        difficulty.addActionListener ( this ) ;
        m.add ( difficulty ) ;
        mb.add ( m ) ;
        startTime=System.currentTimeMillis();
        this.setJMenuBar ( mb ) ;
        this.add ( p ) ;
        this.add ( mineLabel , BorderLayout.SOUTH ) ;
        this.pack ( ) ;
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible ( true ) ;
        timer.start();
    }

    public void fillMines ( ) {
        int needed = numMines ;
        while ( needed > 0 ) {
            int x = ( int ) Math.floor ( Math.random ( ) * rows ) ;
            int y = ( int ) Math.floor ( Math.random ( ) * cols ) ;
            if ( ! mines [ ( rows * y ) + x ] ) {
                mines [ ( rows * y ) + x ] = true ;
                needed -- ;
            }
        }
    }

    public void fillNumbers ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                int cur = ( rows * y ) + x ;
                if ( mines [ cur ] ) {
                    numbers [ cur ] = 0 ;
                    continue ;
                }
                int temp = 0 ;
                boolean l = ( x - 1 ) >= 0 ;
                boolean r = ( x + 1 ) < rows ;
                boolean u = ( y - 1 ) >= 0 ;
                boolean d = ( y + 1 ) < cols ;
                int left = ( rows * ( y ) ) + ( x - 1 ) ;
                int right = ( rows * ( y ) ) + ( x + 1 ) ;
                int up = ( rows * ( y - 1 ) ) + ( x ) ;
                int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
                int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
                int down = ( rows * ( y + 1 ) ) + ( x ) ;
                int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
                int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;
                if ( u ) {
                    if ( mines [ up ] ) {
                        temp ++ ;
                    }
                    if ( l ) {
                        if ( mines [ upleft ] ) {
                            temp ++ ;
                        }
                    }
                    if ( r ) {
                        if ( mines [ upright ] ) {
                            temp ++ ;
                        }
                    }
                }
                if ( d ) {
                    if ( mines [ down ] ) {
                        temp ++ ;
                    }
                    if ( l ) {
                        if ( mines [ downleft ] ) {
                            temp ++ ;
                        }
                    }
                    if ( r ) {
                        if ( mines [ downright ] ) {
                            temp ++ ;
                        }
                    }
                }
                if ( l ) {
                    if ( mines [ left ] ) {
                        temp ++ ;
                    }
                }
                if ( r ) {
                    if ( mines [ right ] ) {
                        temp ++ ;
                    }
                }
                numbers [ cur ] = temp ;
            }
        }
    }

    public void setupI ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                mines [ ( rows * y ) + x ] = false ;
                clickdone [ ( rows * y ) + x ] = false ;
                clickable [ ( rows * y ) + x ] = true ;
                buttons [ ( rows * y ) + x ] = new JButton ( /*"" + ( x * y )*/) ;
                buttons [ ( rows * y ) + x ].setPreferredSize ( new Dimension (
                        45 , 45 ) ) ;
                buttons [ ( rows * y ) + x ].addActionListener ( this ) ;
                buttons [ ( rows * y ) + x ].addMouseListener ( this ) ;
            }
        }
        fillMines ( ) ;
        fillNumbers ( ) ;
        startTime=System.currentTimeMillis();
    }

    public void setupI2 ( ) {
        this.remove ( p ) ;
        p = new JPanel ( ) ;
        layout = new GridLayout ( rows , cols ) ;
        p.setLayout ( layout ) ;
        buttons = new JButton [ rows * cols ] ;
        mines = new boolean [ rows * cols ] ;
        clickdone = new boolean [ rows * cols ] ;
        clickable = new boolean [ rows * cols ] ;
        numbers = new int [ rows * cols ] ;
        setupI ( ) ;
        for ( int i = 0 ; i < ( rows * cols ) ; i ++ ) {
            p.add ( buttons [ i ] ) ;
        }
        this.add ( p ) ;
        this.pack ( ) ;
        fillMines ( ) ;
        fillNumbers ( ) ;
        startTime=System.currentTimeMillis();
    }

    public void setup ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                mines [ ( rows * y ) + x ] = false ;
                clickdone [ ( rows * y ) + x ] = false ;
                clickable [ ( rows * y ) + x ] = true ;
                buttons [ ( rows * y ) + x ].setEnabled ( true ) ;
                buttons [ ( rows * y ) + x ].setText ( "" ) ;
            }
        }
        fillMines ( ) ;
        fillNumbers ( ) ;
        lost = false ;
        startTime=System.currentTimeMillis();
        updateLabel();
    }

    public static void main ( String [ ] args ) {
        new MineSweeper ( ) ;
    }

    public void actionPerformed ( ActionEvent e ) {
        if(e.getSource()==timer){
            updateLabel();
            return;
        }
        if ( e.getSource ( ) == difficulty ) {
            rows = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
                    this , "Rows" , "Rows" , JOptionPane.PLAIN_MESSAGE , null ,
                    null , 10 ) ) ;
            cols = Integer.parseInt ( ( String ) JOptionPane.showInputDialog (
                    this , "Columns" , "Columns" , JOptionPane.PLAIN_MESSAGE ,
                    null , null , 10 ) ) ;
            numMines = Integer.parseInt ( ( String ) JOptionPane
                    .showInputDialog ( this , "Mines" , "Mines" ,
                            JOptionPane.PLAIN_MESSAGE , null , null , 10 ) ) ;
            setupI2 ( ) ;
        }
        if ( ! won ) {
            for ( int x = 0 ; x < rows ; x ++ ) {
                for ( int y = 0 ; y < cols ; y ++ ) {
                    if ( e.getSource ( ) == buttons [ ( rows * y ) + x ]
                            && ! won && clickable [ ( rows * y ) + x ] ) {
                        doCheck ( x , y ) ;
                        break ;
                    }
                }
            }
        }
        if ( e.getSource ( ) == newGameButton ) {
            setup ( ) ;
            won = false ;
            return ;

        }
        checkWin ( ) ;
        updateLabel();
    }

    public void mouseEntered ( MouseEvent e ) {

    }

    public void mouseExited ( MouseEvent e ) {

    }

    public void mousePressed ( MouseEvent e ) {
        if ( e.getButton ( ) == 3 ) {
            flags=0;
            for ( int x = 0 ; x < rows ; x ++ ) {
                for ( int y = 0 ; y < cols ; y ++ ) {
                    if ( e.getSource ( ) == buttons [ ( rows * y ) + x ] ) {
                        clickable [ ( rows * y ) + x ] = ! clickable [ ( rows * y )
                                + x ] ;
                    }
                    if ( ! clickdone [ ( rows * y ) + x ] ) {
                        if ( ! clickable [ ( rows * y ) + x ] ) {
                            buttons [ ( rows * y ) + x ].setText ( "X" ) ;
                            flags ++ ;
                        } else {
                            buttons [ ( rows * y ) + x ].setText ( "" ) ;
                        }
                    }
                }
            }
            updateLabel();
        }
    }

    private void updateLabel(){
        mineLabel.setText ( "mines: " + numMines + " marked: " + flags + " Time: " + (System.currentTimeMillis()-startTime)/1000 + "s ") ;
    }
    public void mouseReleased ( MouseEvent e ) {

    }

    public void mouseClicked ( MouseEvent e ) {

    }

    public void doCheck ( int x , int y ) {
        int cur = ( rows * y ) + x ;
        boolean l = ( x - 1 ) >= 0 ;
        boolean r = ( x + 1 ) < rows ;
        boolean u = ( y - 1 ) >= 0 ;
        boolean d = ( y + 1 ) < cols ;
        int left = ( rows * ( y ) ) + ( x - 1 ) ;
        int right = ( rows * ( y ) ) + ( x + 1 ) ;
        int up = ( rows * ( y - 1 ) ) + ( x ) ;
        int upleft = ( rows * ( y - 1 ) ) + ( x - 1 ) ;
        int upright = ( rows * ( y - 1 ) ) + ( x + 1 ) ;
        int down = ( rows * ( y + 1 ) ) + ( x ) ;
        int downleft = ( rows * ( y + 1 ) ) + ( x - 1 ) ;
        int downright = ( rows * ( y + 1 ) ) + ( x + 1 ) ;

        clickdone [ cur ] = true ;
        buttons [ cur ].setEnabled ( false ) ;
        if ( numbers [ cur ] == 0 && ! mines [ cur ] && ! lost && ! won ) {
            if ( u && ! won ) {
                if ( ! clickdone [ up ] && ! mines [ up ] ) {
                    clickdone [ up ] = true ;
                    buttons [ up ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ upleft ] && numbers [ upleft ] != 0
                            && ! mines [ upleft ] ) {
                        clickdone [ upleft ] = true ;
                        buttons [ upleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ upright ] && numbers [ upright ] != 0
                            && ! mines [ upright ] ) {
                        clickdone [ upright ] = true ;
                        buttons [ upright ].doClick ( ) ;
                    }
                }
            }
            if ( d && ! won ) {
                if ( ! clickdone [ down ] && ! mines [ down ] ) {
                    clickdone [ down ] = true ;
                    buttons [ down ].doClick ( ) ;
                }
                if ( l && ! won ) {
                    if ( ! clickdone [ downleft ] && numbers [ downleft ] != 0
                            && ! mines [ downleft ] ) {
                        clickdone [ downleft ] = true ;
                        buttons [ downleft ].doClick ( ) ;
                    }
                }
                if ( r && ! won ) {
                    if ( ! clickdone [ downright ]
                            && numbers [ downright ] != 0
                            && ! mines [ downright ] ) {
                        clickdone [ downright ] = true ;
                        buttons [ downright ].doClick ( ) ;
                    }
                }
            }
            if ( l && ! won ) {
                if ( ! clickdone [ left ] && ! mines [ left ] ) {
                    clickdone [ left ] = true ;
                    buttons [ left ].doClick ( ) ;
                }
            }
            if ( r && ! won ) {
                if ( ! clickdone [ right ] && ! mines [ right ] ) {
                    clickdone [ right ] = true ;
                    buttons [ right ].doClick ( ) ;
                }
            }
        } else {
            buttons [ cur ].setText ( "" + numbers [ cur ] ) ;
            if ( ! mines [ cur ] && numbers [ cur ] == 0 ) {
                buttons [ cur ].setText ( "" ) ;
            }
        }
        if ( mines [ cur ] && ! won ) {
            buttons [ cur ].setText ( "0" ) ;
            doLose ( ) ;
        }
    }

    public void checkWin ( ) {
        for ( int x = 0 ; x < rows ; x ++ ) {
            for ( int y = 0 ; y < cols ; y ++ ) {
                int cur = ( rows * y ) + x ;
                if ( ! clickdone [ cur ] ) {
                    if ( mines [ cur ] ) {
                        continue ;
                    } else {
                        return ;
                    }
                }
            }
        }

        doWin ( ) ;
    }

    public void doWin ( ) {
        if ( ! lost && ! won ) {
            won = true ;
            JOptionPane.showMessageDialog ( null ,
                    "you win in " + (System.currentTimeMillis()-startTime)/1000 + " seconds!\nstarting a new game" , "you lose" ,
                    JOptionPane.INFORMATION_MESSAGE ) ;
            newGameButton.doClick ( ) ;
        }
    }

    public void doLose ( ) {
        if ( ! lost && ! won ) {
            lost = true ;
            for ( int i = 0 ; i < rows * cols ; i ++ ) {
                if ( ! clickdone [ i ] ) {
                    buttons [ i ].doClick ( 0 ) ;
                }
            }
            JOptionPane.showMessageDialog ( null ,
                    "you lose!\nstarting a new game" , "you lose" ,
                    JOptionPane.ERROR_MESSAGE ) ;
            setup ( ) ;
        }
    }
}

thank u so much! im giving you credit for some code im using. one last question i think. any way to change the colors of any of this? like the grid or numbers or words etc? i thought itd be simple but i just cant figure it out

thank u so much! im giving you credit for some code im using. one last question i think. any way to change the colors of any of this? like the grid or numbers or words etc? i thought itd be simple but i just cant figure it out

look into the setForgroundColor(Color) method of Component for the text of the buttons, also setBackgroundColor(Color)

insert buttons[i].setForgroundColor(Color.red) after 134 and import java.awt.Color to the top of the file see if that helps

can i change the colors of anything in this game? like the numbers or the grid to make it look cooler?

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.