Eric
Eric

Reputation: 373

Creating a visible grid in a JPanel

What I'm trying to do

I want to create an API (personal one) that allows me to input a dimension (say 10x10) and it creates a visible grid with 10 squares by 10 squares, with the added 'feature' of being able to change the fill of any of the squares via a method call. Not trying to use a mouse listener or any listeners of any sort.

My thought process is something like this: Have the main JPanel that holds the grid recursively add 'box' objects and reference each one with an array location. My issue isn't the main JPanel, that I've got down easily enough. My issue is the object it's adding. I can't figure out what sort of component this should be. I attempted using a JPanel but couldn't get anything to be visible. Besides, the 'grid' look wouldn't be there either.

I'm guessing I'm going to have to utilize swing.Graphics or Graphics2D but every example I've found online hasn't worked out well for me. Looking for advice on using Graphics, or if there's an even better way of getting what I want, I'd gladly try it out.

Upvotes: 0

Views: 4506

Answers (2)

Paul Samsotha
Paul Samsotha

Reputation: 209012

  1. Have a MainPanel class that takes the dimension arugments and set it's layout to GridLayout based on the specified dimension

    public class MainPanel extends JPanel {
        public MainPanel(int rows, int cols) {
            setLayout(new GridLayout(rows, cols));
        }
    }
    
  2. Create an interface that has a draw() method

    public interface Drawable {
        void draw(Graphics g);
    }
    
  3. Create a custom panel that has a Drawable property, in which you will call it's draw method

    public class DrawPanel extends JPanel {
        private Drawable drawable;
    
        public DrawPanel() {}
    
        public DrawPanel(Drawable drawable) {
            this.drawable = drawable;
        }
    
        public void setDrawable(Drawable drawable) {
            this.drawable = drawable;
            repaint();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (drawable != null) {
                drawable.draw(g);
            }
        }
    }
    
  4. Create a 2D array of your DrawPanels in the MainPanel class, just you you can access them by index, if you need to to

    public class MainPanel extends JPanel {
        private DrawPanel[][] panels;
        public MainPanel(int rows, int cols) {
            setLayout(new GridLayout(rows, cols));
            panels = new DrawPanel[rows][cols];
        }
    }
    
  5. Populate the array with new DrawPanels and add them to the MainPanel

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            DrawPanel panel = new DrawPanel();
            panels[i][j] = panel;
            MainPanel.this.add(panel);
        }
    }
    
  6. Implement the Drawable interface with some whatever/how many implemtations you want. Like

    public class Ball implements Drawable {
        private int x, y;
        private JPanel surface;
        public Ball(int x, int y, JPanel surface) {
            this.x = x;
            this.y = y;
            this.surface = surface;
        }
    
        @Override
        public void draw(Graphics g) {
            g.fillOval(x, y, sirface.getWidth(), surface.getHeight());
        }
    }
    
  7. Add you drawable object to a panel

    JPanel panel = panels[3][4];
    panel.setDrawable(new Ball(0, 0, panel));
    
  8. You can make as many different implementations of Drawable as you want, and each panel can have a different object drawn.

    public class Midget implements Drawable {
        @Override
        public void draw(Graphics g) {
            // draw midget
        }
    }
    ....
    panels[5][5].setDrawable(new Midget());
    

Upvotes: 2

Braj
Braj

Reputation: 46841

Try below sample code using JLabel

JPanel panel = new JPanel(new GridLayout(10, 10));
JLabel[] labels = new JLabel[20];

Color[] colors = new Color[] { Color.GREEN, Color.RED, Color.BLUE };
Random random = new Random();

for (int i = 0; i < labels.length; i++) {
    JLabel label = new JLabel();

    label.setBackground(colors[random.nextInt(colors.length)]);
    label.setOpaque(true);

    panel.add(label);
    labels[i] = label;
}

snapshot:

enter image description here

Upvotes: 2

Related Questions