0

I'm trying to print out a maze. I'm new to Java Swing graphics, and my initial thought was to add JPanel components of each cell to the JFrame. I get garbage results when I run this code.

Is there any way I can change this code minimally so that all the panels are printed? Note that CurrPos, Wall, Unvisited, and Visited are subclasses of JFrame, which implement the painComponent method.

Here's the code:

import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class DrawMaze {
    public final int WIDTH = 500;
    public final int HEIGHT = 500;
    JFrame frame;

    public void initializeMaze(){
        frame = new JFrame("Maze");
        frame.getContentPane().setLayout(null);
        frame.setSize(WIDTH, HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void drawMaze(String[][] maze, int[] currPosArray) {
        //frame.removeAll();

        addMazeContentsToList(maze, currPosArray);
        frame.setVisible(true);
    }

    private void addMazeContentsToList(String[][] maze, int[] currPosArray)  {
        for (int i = 0; i<7; i++){
            for (int j = 0; j<9; j++){
                if ((i%2 == 1 && j%2 == 0) ||(i%2 == 0 && j%2 == 1) ){
                    Wall wall = drawWall(i, j);
                    frame.add(wall);
                    wall.repaint();
                }
                else if (i%2 ==0 && j%2 ==0){
                    if (i==currPosArray[0] && j==currPosArray[1]){
                        CurrPos currPos = drawCurrPos(i/2, j/2);
                        frame.add(currPos);
                        currPos.repaint();
                    }
                    else{
                        if (maze[i][j].equals("Unexplored")){
                            Unvisited unvisited = drawUnvisited(i/2,j/2);
                            frame.add(unvisited);
                            unvisited.repaint();
                        }
                        else{
                            Visited visited = drawVisited(i/2,j/2);
                            frame.add(visited);
                            visited.repaint();
                        }
                    }
                }
            }
        }
    }

    private Visited drawVisited(int i, int j) {
        int x = (int) Math.floor((i/4.0)*WIDTH);
        int y =  (int) Math.floor((j/5.0)*HEIGHT);
        int width = (int) Math.floor(WIDTH/4.0);
        int height =    (int) Math.floor(HEIGHT/5.0);
        return new Visited(x, y, width, height);
    }

    private Unvisited drawUnvisited(int i, int j) {
        int x = (int) Math.floor((i/4.0)*WIDTH);
        int y =  (int) Math.floor((j/5.0)*HEIGHT);
        int width = (int) Math.floor(WIDTH/4.0);
        int height =    (int) Math.floor(HEIGHT/5.0);
        //System.out.println(x);
        //System.out.println(y);
        System.out.println(width);
        System.out.println(height);
        return new Unvisited(x, y, width, height);
    }

    private CurrPos drawCurrPos(int i, int j) {
        int x = (int) Math.floor((i/4.0)*WIDTH);
        int y =  (int) Math.floor((j/5.0)*HEIGHT);
        int width = (int) Math.floor(WIDTH/4.0);
        int height =    (int) Math.floor(HEIGHT/5.0);
        return new CurrPos(x, y, width, height);
    }

    private Wall drawWall(int i, int j) {

        //vertical wall
        if (i%2 ==1){
            int relativeX = (i+1)/2;
            int relativeY = j/2;
            int width = (int) Math.floor((1/4.0)*WIDTH*(0.2));
            int height = (int) Math.floor((1/5.0)*HEIGHT);
            int x = (int) Math.floor(((relativeX/4.0)*WIDTH - width*0.5));
            int y = (int) (Math.floor((relativeY/5.0)*HEIGHT));
            return new Wall(x, y, width, height);
        }
        //horizontal wall
        else{
            int relativeX = i/2;
            int relativeY = (j+2)/2;
            int width = (int) Math.floor((1/4.0)*WIDTH);
            int height = (int) Math.floor((1/5.0)*HEIGHT*(0.2));
            int x = (int) (Math.floor((relativeY/4.0)*WIDTH));
            int y = (int) Math.floor(((relativeX/5.0)*HEIGHT - height*0.5));
            return new Wall(x, y, width, height);
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    *"Note that `CurrPos`, `Wall`, `Unvisited`, and `Visited` are subclasses of `JFrame`, which implement the `painComponent` method."* 1) It's `paintComponent(..)` not `painComponent(..)`. 2) Either would be a new method for `JFrame`. (always use the `@Override` notation when you think you're chaning the behaviour of an existing method!) 3) Don't extend `JFrame` here (I've never seen a good case for extending frame, and certainly not this one. 4) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Oct 24 '17 at 05:45
  • 1
    .. 5) *"Is there any way I can change this code minimally so that all the panels are printed?"* I doubt it. Toss this crap out and start again. Use one frame (but don't extend it). Add one panel (`JPanel`) too it, and custom paint the entire map in that panel by overriding the `paintCompomonent(Graphics)` method. Also override the `getPreferredSize()` method of the panel wo when the frame is packed, it ends up the right size. 6) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Oct 24 '17 at 05:48
  • How to I instantiate square elements 1-by-1 with different sizes and colours? – LeBron James Oct 24 '17 at 05:59
  • With custom painting, only the custom painted panel needs to be instantiated. – Andrew Thompson Oct 24 '17 at 06:02
  • What kind of object is added to the "custom painted panel"? My plan is to iterate through the maze array and instantiate some Java image objects on the fly, which will be added to the JFrame/JPanel in some way/shape/form. – LeBron James Oct 24 '17 at 06:11
  • 1
    *"My plan is to iterate through the maze array and instantiate some Java image objects on the fly,"* No. That is inefficient, instantiate the images during construction of the panel, then use them as many times as needed. *"which will be added to the JFrame/JPanel in some way/shape/form."* 'Add' them using `Graphics.drawImage(..)` (used in the `paintComponent(Graphics)` method. – Andrew Thompson Oct 24 '17 at 07:38

0 Answers0