Search code examples
javaarrayspaintcomponent

Double dimensional array with colours doesn't paint in paintComponent


I've been working on a dots look-a-like, but I'm having trouble painting the dots on the board. The array seems to work but it doesn't want to paint it.

Sorry, some of my variables are in Dutch but that shouldn't really pose too many confusion.

public class Bord extends JFrame{

    Slang slang = new Slang();
    Tile[][] tile = new Tile[6][6];

    private JPanel menuPanel;
    private JPanel gridPanel;

    private JLabel levelTitel;
    private JLabel levelNummer;

    private JLabel scoreTitel;
    private JLabel scoreNummer;

    private JLabel targetTitel;
    private JLabel targetNummer;

    private JLabel timeTitel;
    private JLabel timeNummer;

    private JLabel pauzeKnop;

    public Bord() {
        super("Dots");
        //setLocationRelativeTo(this);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        maakAttributen();
        maakListeners();
        maakLayout();
        pack();

        setSize(650, 750);

        setVisible(true);

        getContentPane();
        repaint();

        //TODO automatic size

    }

    public void maakAttributen() {


        levelTitel = new JLabel("level");
        levelNummer = new JLabel("1");

        scoreTitel = new JLabel("score");
        scoreNummer = new JLabel("2");

        targetTitel = new JLabel("target");
        targetNummer = new JLabel("3");

        timeTitel = new JLabel("time");
        timeNummer = new JLabel("4");

        //TODO image in knop zetten
        pauzeKnop = new JLabel("PAUZE");

    }

    public void maakListeners() {

    }

    public void maakLayout() {
        JPanel menuPanel = new JPanel(new GridLayout(0, 5, 5, 5));
        JPanel gridPanel = new JPanel(new GridLayout(0, 7, 5, 5));

        add(menuPanel, BorderLayout.PAGE_START);
        add(gridPanel, BorderLayout.CENTER);

        //menu attributen aan menu toevoegen
        menuPanel.add(levelTitel);
        menuPanel.add(scoreTitel);
        menuPanel.add(targetTitel);
        menuPanel.add(timeTitel);
        menuPanel.add(pauzeKnop);

        menuPanel.add(levelNummer);
        menuPanel.add(scoreNummer);
        menuPanel.add(targetNummer);
        menuPanel.add(timeNummer);

        //grid met dots toevoegen

        for (int x = 0; x < 6; x++) {
            for (int y = 0; y < 6; y++) {
                RandomKleur kleur = new RandomKleur();
                tile[x][y] = new Tile(kleur.getKleur());
                gridPanel.add(new myDots());
            }
        }
    }

    private class myDots extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            int h = getHeight();
            int w = getWidth();
            super.paintComponent(g);

            for (int x = 0; x < 6; x++) {
                for (int y =0; y < 6; y++) {
                    g.setColor(tile[x][y].getKleur());
                    g.fillOval(h / 2, w / 2, 33, 33);
                }
            }
        }
    }
}

I've tried debugging it and it gives some kind of null pointer exception sometimes.


Solution

  • You basic painting logic is wrong. You are adding 36 Dot panels to the frame, but then in the painting logic you are repainting all 36 dots on top of one another so only the last dot painted will display. The paintComponent() method should only be painting a single dot.

    You need to change your MyDots class to accept a Tile as a parameter and then save the Tile object as an instance variable of the class. Then the code would be something like:

    for (int x = 0; x < 6; x++) {
        for (int y = 0; y < 6; y++) {
            RandomKleur kleur = new RandomKleur();
            tile[x][y] = new Tile(kleur.getKleur());
            //gridPanel.add(new myDots());
            gridPanel.add(new myDots(tile[x][y]));
        }
    }
    

    I don't know if you even need the tile array, because now the MyDots class has the tile information.

    Then Your painting logic should be something like:

        //for (int x = 0; x < 6; x++) {
            //for (int y =0; y < 6; y++) {
                //g.setColor(tile[x][y].getKleur());
                g.setColor(tile.getKleur()); // where "tile" is the instance variable
                g.fillOval(h / 2, w / 2, 33, 33);
            //}
        //}
    

    Who knows why you get the NPE, because the exception is not related to the code you posted.

    By the way class name should start with an upper case character. It should be "MyDot".

    Edit:

    Do I have to create a new method in MyDots?

    You need to create a constructor for your class:

    public class MyDots
    {
        private Tile tile;
    
        public MyDots(Tile tile)
        {
            this.tile = tile;
        }
    
        @Override
        protectect paintComponent(Graphics g)
        ...
    }