Search code examples
javanested-loops

Nesting for-loop in Order to Create Brick Wall


I am new to programming and this is my first time posting to this site. I am currently working on an assignment which will allow a user to input a number between 1 and 20, and then will create a brick wall based upon the number of brick layers the user entered into the JTextField. I was able to create one row, but I don't really understand nesting statements, and all of the examples I've looked at on the web just confuse me more, so I was wondering if someone could possibly help me to better understand nesting for-loops.

//Package List
import java.awt.*;
import java.applet.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;

public class Wall extends JApplet implements KeyListener {



//Component declaration
    JLabel directions;
    JTextField input;
    //Variable declaration
    int startX = 50;
    int startY = 650;
    int width = 50;
    int height = 20;
    int spacing = 2;


    //Method declaration
    public void init() 
    {
        getContentPane().setBackground(new Color (128, 128, 128));//Changes backround of JApplet to black
        //Set JTextField and JLabel
        setLayout (new FlowLayout( ));
        directions = new JLabel("Enter in any number between 1 and 20 and then press Enter on your keyboard.");
        input = new JTextField ( 10 );
        add (directions );
        add (input);

        //Key listener
        addKeyListener( this );
        setFocusable( true );   
    }

    //Method declaration 
    public void paint(Graphics g) 
    {
        super.paint (g);

        for (int col=1; col<= 8; col++)
         {
         // for (int row; row<=20; row++)
            {   g.setColor (Color.RED);
                g.fillRect (startX, startY, 50, 20);
                startX =  startX + spacing + width;
            }

         }
    }

    //Key event methods
    public void keyReleased( KeyEvent ke ){}
    public void keyTyped (KeyEvent ke ) {}
    public void keyPressed ( KeyEvent ke )
    {
        int key = ke.getKeyCode ( );    
        if (key == KeyEvent.VK_ENTER)
        {
        }

    }

Solution

  • You need to calculate the x/y position of the brick based on the current row/col. Now, you could simply initialise these values at the start of each loop and increment as required, or you could use a little maths...

    Bricks

    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import javax.swing.JApplet;
    import javax.swing.JLabel;
    import javax.swing.JTextField;
    
    public class AnotherBrickInTheWall extends JApplet {
    
    //Component declaration
        JLabel directions;
        JTextField input;
        //Variable declaration
        int startX = 0;
        int startY = 50;
        int width = 50;
        int height = 20;
        int spacing = 2;
    
        //Method declaration
        public void init() {
            getContentPane().setBackground(new Color(128, 128, 128));//Changes backround of JApplet to black
            //Set JTextField and JLabel
            setLayout(new FlowLayout());
            directions = new JLabel("Enter in any number between 1 and 20 and then press Enter on your keyboard.");
            input = new JTextField(10);
            add(directions);
            add(input);
        }
    
        //Method declaration 
        @Override
        public void paint(Graphics g) {
            super.paint(g);
    
            for (int row = 0; row < 8; row++) {
                int y = startY + (row * (height + spacing));
                for (int col = 0; col < 8; col++) {
                    int x = startX + (col * (width + spacing));
                    System.out.println(x + "x" + y);
                    g.setColor(Color.RED);
                    g.fillRect(x, y, width, height);
                }
            }
        }
    }
    

    Now, you should never paint on a component which has components added to, this will cause the painting to appear over the top of the components and end up with all sorts of painting issues.

    Instead, create a custom component, extending from something like JPanel and override it's paintComponent method instead and place your custom painting here.

    You could then add your controls another JPanel and using a BorderLayout on your applet, add these two panels, the fields in the NORTH position and wall in the CENTER position

    Updated

    If you wanted to get "really" fancy, you could even adjust the x position based on the current row, for example...

    Bricks

    int xOffset = 0;
    for (int row = 0; row < 8; row++) {
        int y = startY + (row * (height + spacing));
        if (row % 2 == 0) {
            xOffset = width / 2;
        } else {
            xOffset = 0;
        }
        for (int col = 0; col < 8; col++) {
            int x = xOffset + (startX + (col * (width + spacing)));
            System.out.println(x + "x" + y);
            g.setColor(Color.RED);
            g.fillRect(x, y, width, height);
        }
    }
    

    Also, JTextField is has an ActionListener which is triggered when the field is actioned, typically by the user pressing Enter. This means that you shouldn't need the KeyListener.

    See How to Use Text Fields for more details.