marpataa marpataa - 19 days ago 5
Java Question

Java Swing JFrame doesn't open (Minesweeper game)?

I made a minesweeper game in Java using Swing, but when i run it, JFrame doesn't pop up? (No errors)
It runs, but no window shows up. Tried to debug with no success.

I really appreciate your help :)

Note that in class GameBoard:

imgs = new Image[13]; //Number of images used
//Loading images, used later
for (int i = 0; i < 13; i++) {
imgs[i] = (new ImageIcon(i + ".png")).getImage();
}


These lines load numbers representing images (13 images), created by me, and these imgs are loadid depending on the mouseadapter.

This is the MineSweeper class with the main method:

package minesweeper;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class MineSweeper extends JFrame {

public JLabel label;

public MineSweeper(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
this.setLocationRelativeTo(null);
this.setTitle("Minesweeper");

label = new JLabel("");
this.add(label, BorderLayout.SOUTH);

GameBoard game = new GameBoard(label);
this.add(game);

setResizable(false);

}


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
MineSweeper jf = new MineSweeper();
jf.setVisible(true);
}
});
}




}


An this is the GameBoard class:

package minesweeper;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;



public class GameBoard extends JPanel {


//Adding constant variables
private final int SIZE_OF_CELL = 20;
private static final int NUM_OF_ROWS = 20;
private static final int NUM_OF_CL = 20;
private final int SIZE_OF_FIELD = NUM_OF_ROWS * NUM_OF_CL;
//Adding other variables
private int NUM_OF_MINES_LEFT;
private Image[] imgs;
private static int[][] gameboard;
public static int mines = 40;

private int all_cells;
private static JLabel label;
boolean gamestarted = true; // Game is in progress, already started

//Constructor 1 parameter
public GameBoard(JLabel inputlabel) {

this.label = inputlabel;
imgs = new Image[13]; //Number of images used
//Loading images, used later
for (int i = 0; i < 13; i++) {
imgs[i] = (new ImageIcon(i + ".png")).getImage();
}

setDoubleBuffered(true);
addMouseListener(new Manager());
StartNewGame();
}


//Find mines around cell[i][j]
public static int FindMines(int ro, int co){
int cnt=0;

for(int y=-1;y<=1;y++){
for(int x = -1; x<=1;x++){
if(x==0 && y ==0) continue;
if(ro+y<0) continue;
if(co+x<0) continue;
if(gameboard[ro+y][co+x]==19) cnt++;
}
}
return cnt;
}



public static void StartNewGame(){



//NUM_OF_MINES_LEFT = 40; // Default value for number of mines is 30
gameboard = new int[20][20];
int minesleft=mines;
int row,col;
// int mines = NUM_OF_MINES_LEFT;
Random rng=new Random();
label.setText(Integer.toString(minesleft));

//initialize mine field
for(int i=0;i<20;i++){
for (int j=0;j<20;j++){
gameboard[i][j]=10;//default value is 10 -> its covered
}
}

//Set mines in random positions
while (mines>0){
row=rng.nextInt(NUM_OF_ROWS);
col=rng.nextInt(NUM_OF_CL);
if ((gameboard[row][col])!=19){
gameboard[row][col]+=9;;
minesleft--;
}
}



//Set numbers
for(int i=0;i<20;i++){
for (int j=0;j<20;j++){

if(gameboard[i][j]==19) gameboard[i][j]=19;

if(gameboard[i][j]==10){
gameboard[i][j]+= FindMines(i,j);
}
}
}

}



//public int FindEmptyCells(){



//}
@Override
public void paintComponent(Graphics grap){

int gamewon=0;
int[][] temp = new int[20][20];

for(int i=0;i<20;i++){
for(int j=0;j<20;j++){

temp[i][j]=gameboard[i][j];

if(gamestarted && temp[i][j]==9) gamestarted=false;

if(gamestarted == false){
if(temp[i][j]==19){
temp[i][j]= 9;
}else if(temp[i][j]==29){//10+11 for mark
temp[i][j]=11;
}else if(temp[i][j]>9){
temp[i][j]=10;
}
}else{
if (temp[i][j] > 19)
temp[i][j] = 11;
else if (temp[i][j] > 9) {
temp[i][j] = 10;
gamewon=1;
}
}
int toload= temp[i][j];
grap.drawImage(imgs[toload],j*15,i*15,this);


}
}

if(gamestarted==true && gamewon==0){
gamestarted=false;
label.setText("You won!");
}else if(gamestarted==false){
label.setText("You Lost!");
}
}

class Manager extends MouseAdapter{

@Override
public void mousePressed(MouseEvent ev){


boolean newpaint = false;

//Get event coordinates
int x= ev.getX();
int y= ev.getY();
int hit_cl= x / 15;
int hit_row= y/ 15;

if(gamestarted==false){
StartNewGame();
repaint();
}


if( (x < 20 * 15) && (y < 20 * 15) ){

if(ev.getButton() == MouseEvent.BUTTON3){

if(gameboard[hit_cl][hit_row] > 9){
newpaint=true;

if(gameboard[hit_cl][hit_row] <= 19){
if(mines > 0){
mines--;
String show=Integer.toString(mines);
gameboard[hit_cl][hit_row]+=11;
label.setText(show);

}else{
label.setText("Marks: 0");
}
}else{
mines++;
String show=Integer.toString(mines);
label.setText(show);
gameboard[hit_cl][hit_row]-=11;
}

}


}else{
if(gameboard[hit_cl][hit_row] > 19){
return;
}
if((gameboard[hit_cl][hit_row] > 9) && (gameboard[hit_cl]
[hit_row] <29)){
newpaint=true;
gameboard[hit_cl][hit_row]-=10;

if(gameboard[hit_cl][hit_row] == 9) gamestarted=false;
//if(gameboard[hit_cl][hit_row] == 10); //find_empty();


}
}
if(newpaint==true) repaint();
}

}

}

}

Answer

What did you do to debug? :)

The most obvious reason for the program to run forever is that it never leaves a loop.

while (mines>0){                          
        row=rng.nextInt(NUM_OF_ROWS);
        col=rng.nextInt(NUM_OF_CL);
        if ((gameboard[row][col])!=19){
            gameboard[row][col]+=9;;
            minesleft--;
        }
    }

This part of your StartNewGame() method (GameBoard class) is causing an endless loop, mines variable is never updated inside the loop.

Giving a fast look to your code i can note some bad practices, for example :

  • You should not control the game state or setting labels text inside paintComponent() method. This method is called automatically, and it should only paint all the components. All the "logic" inside it could slow down your program, because you can not control how many times the method gets called (of course you can force the method to be called with repaint() method, for example).
  • You should follow java naming conventions

Hope this helps :)