2

I'm am new to graphics in java and for some reason the graphics are not displaying on the jframe. I am confused of how to set up and instantiate the graphics. There could also be a stupid error in the code that im just not seeing. Thanks for any feedback!

Map Class

public class Map extends JPanel{

private static int WIDTH;
private static int HEIGHT;
private static int ROWS;
private static int COLS;
private static int TILE_SIZE;
private static int CLEAR = 0;
private static int BLOCKED = 1;

private static int[][] GRID;

public Map(int w, int h, int t){

    WIDTH = w;
    HEIGHT = h;
    TILE_SIZE = t;
    ROWS = HEIGHT/TILE_SIZE;
    COLS = WIDTH/TILE_SIZE;

    GRID = new int[ROWS][COLS];

    for (int row = 0; row < ROWS; row++){
        for (int col = 0; col < COLS; col++){
            GRID[row][col] = BLOCKED;
        }
    }

    randomMap();
}

public void randomMap(){
    int row = 0;
    int col = 0;
    int turn;

    Random rand = new Random();

    GRID[row][col] = CLEAR;

    do{
    turn = rand.nextInt(2)+1;
    if (turn == 1)
        row++;
    else
        col++;
    GRID[row][col] = CLEAR;
    }while(row<ROWS-1 && col<COLS-1);

    if (row == ROWS-1){
        for (int i = col; i < COLS; i++){
            GRID[row][i] = CLEAR;
        }
    }
    else{
        for (int i = row; i < ROWS; i++){
            GRID[i][col] = CLEAR;
        }
    }


}


public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;

    for (int row = 0; row < WIDTH; row++){
        for (int col = 0; col < HEIGHT; col++){
            if (GRID[row][col] == 1){
                g2d.setColor(Color.BLACK);
                g2d.fillRect(row*TILE_SIZE, col*TILE_SIZE, TILE_SIZE, TILE_SIZE);
            }else{
                g2d.setColor(Color.WHITE);
                g2d.fillRect(row*TILE_SIZE, col*TILE_SIZE, TILE_SIZE, TILE_SIZE);
            }
        }
    }
}

public void displayConsole(){

    for (int row = 0; row < ROWS; row++){
        for (int col = 0; col < COLS; col++){

            System.out.print(GRID[row][col] + "   ");
        }
        System.out.println("");
        System.out.println("");
    }
}

}

Game Class

public class Game extends JFrame{

private Map map;

public Game(){

    setLayout(null);
    setBounds(0,0,500,500);
    setSize(500,500);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Map map = new Map(500,500,50);
    map.displayConsole();

    add(map);
    repaint();
    setVisible(true);
}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Game game = new Game();

}

}
  • 2
    `setLayout(null);` Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson May 11 '15 at 23:46
  • `public class Game extends JFrame{` Ugghh.. I was about to turn those two classes into a single MCVE.. Do you know how many source codes I've worked on called `Game`? Since I reserve a single package in my IDE for testing junk codes, it means I'd need to delete another example before proceeding. Please make class names descriptive and distinct. One way to do that is to add your name to the name of the game. You can bet I have no other codes here called `public class PeterCinibulkGame extends JFrame{` .. – Andrew Thompson May 11 '15 at 23:52

2 Answers2

4

It is likely the painted component is of size 0x0. A custom painted component should return the preferred size of the component.

After the component is added to a frame, pack the frame to ensure the frame is the exact size needed to display the component.

Of course, either use or set an appropriate layout/constraint in the frame. In this case, I would use the default layout of BorderLayout and the default constraint of CENTER.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

Andrew is correct. I had to re-do the layout to get this to work. I added the code for perferredSize() and minimumSize(), and I added a call to pack() and removed the setLayout(null). Also, you have a problem calculating your HEIGHT and WIDTH, they don't line up to ROWS and COLS and will throw Index Out Of Bounds.

Corrected code below.

class Game extends JFrame
{

   private Map map;

   public Game()
   {

//      setLayout( null );
      setBounds( 0, 0, 500, 500 );
      setSize( 500, 500 );
      setResizable( false );
      setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

      Map map = new Map( 500, 500, 50 );
      map.displayConsole();

      add( map );
      pack();
      repaint();
      setVisible( true );
   }

   public static void main( String[] args )
   {
      // TODO Auto-generated method stub

      Game game = new Game();


   }

}

class Map extends JPanel
{

   private static int WIDTH;
   private static int HEIGHT;
   private static int ROWS;
   private static int COLS;
   private static int TILE_SIZE;
   private static int CLEAR = 0;
   private static int BLOCKED = 1;

   private static int[][] GRID;

   public Map( int w, int h, int t )
   {

      WIDTH = w;
      HEIGHT = h;
      TILE_SIZE = t;
      ROWS = HEIGHT / TILE_SIZE;
      COLS = WIDTH / TILE_SIZE;

      GRID = new int[ ROWS ][ COLS ];

      for( int row = 0; row < ROWS; row++ )
         for( int col = 0; col < COLS; col++ )
            GRID[row][col] = BLOCKED;

      randomMap();
   }

   public void randomMap()
   {
      int row = 0;
      int col = 0;
      int turn;

      Random rand = new Random();

      GRID[row][col] = CLEAR;

      do {
         turn = rand.nextInt( 2 ) + 1;
         if( turn == 1 )
            row++;
         else
            col++;
         GRID[row][col] = CLEAR;
      } while( row < ROWS - 1 && col < COLS - 1 );

      if( row == ROWS - 1 )
         for( int i = col; i < COLS; i++ )
            GRID[row][i] = CLEAR;
      else
         for( int i = row; i < ROWS; i++ )
            GRID[i][col] = CLEAR;

   }

   @Override
   public Dimension preferredSize()
   {
//      return super.preferredSize(); //To change body of generated methods, choose Tools | 
      return new Dimension( WIDTH, HEIGHT );
   }

   @Override
   public Dimension minimumSize()
   {
      return preferredSize();
   }




   public void paintComponent( Graphics g )
   {

      super.paintComponent( g );
      Graphics2D g2d = (Graphics2D) g;

      for( int row = 0; row < ROWS; row++ )
         for( int col = 0; col < COLS; col++ )
            if( GRID[row][col] == 1 ) {
               g2d.setColor( Color.BLACK );
               g2d.fillRect( row * TILE_SIZE, col * TILE_SIZE,
                       TILE_SIZE, TILE_SIZE );
            } else {
               g2d.setColor( Color.WHITE );
               g2d.fillRect( row * TILE_SIZE, col * TILE_SIZE,
                       TILE_SIZE, TILE_SIZE );
            }
   }

   public void displayConsole()
   {

      for( int row = 0; row < ROWS; row++ ) {
         for( int col = 0; col < COLS; col++ )
            System.out.print( GRID[row][col] + "   " );
         System.out.println( "" );
         System.out.println( "" );
      }
   }
}
markspace
  • 10,621
  • 3
  • 25
  • 39
  • Heh, heh.. without scrolling down, I read that as `class Mao extends JPanel` rather than `class Map extends JPanel` – Andrew Thompson May 12 '15 at 00:12
  • 1
    `class MaoZedong` wold be kind of a weird class name in this case. I think his bug in the array indexing was a conceptual error: he was using WIDTH and HEIGHT as the bounds, but those are way too large, much larger than the ROWS and COLS he calculates. – markspace May 12 '15 at 00:17
  • *"`class MaoZedong` wold be kind of a weird class name in this case."* True, but `class MaoZedongMap` would at least be (almost guaranteed) unique! ;) – Andrew Thompson May 12 '15 at 00:21