Question

I am unclear on how to repaint a JPanel in my existing code. I also dont understand how paintComponent is being called. Firstly, I would simply like to clear the JPanel but I cannot even do that.

I want to be able to press the "Next Move" button and repaint the JPanel given a change in the grid I am reading colours from. I am having trouble changing the JPanel at all via the calls, revalidate(), removeAll(), and repaint() to my tiles JPanel.

I call these and nothing happens to the existing JPanel below of a tetris grid (tiles) (pictured)..

In the below code i have a nested class that extends JPanel and the setup function creates the window taking in a 2d arraylist grid and constructing the original grid.

How do I at least clear the JPanel or even better redraw with a new grid... I was thinking a method:

    public void redraw(Grid g) {
        removeAll();
                    getColor(); //gets new grid of tiles
                    repaint();
        revalidate();
    }

Inside the nested JPanel class, but this doesnt seem to change the JPanel at all not even clear the current drawing.

Tetris Board reading in original grid

 public class BoardGraphics {

    public ArrayList<ArrayList<Color>> colours;

    private final int width;

    private int height;

    private JFrame display;

    private TetrisSquares tiles;

    private Container c;

    public BoardGraphics(int width, int height,
        ArrayList<ArrayList<Integer>> grid) {
        this.width = width;
        this.height = height;
        colours = new ArrayList<ArrayList<Color>>(width);
        setColor(grid);
        setup();
    }

    public void setup() {
        System.out.println("Let the Tetris Begin");
        display = new JFrame("Tetris Agent");



        final TextArea welcome = new TextArea("Welcome to Tetris", 2, 10,
                TextArea.SCROLLBARS_NONE);

        welcome.setBackground(Color.black);
        welcome.setForeground(Color.red);
        welcome.setFont(new Font("monospaced", 0, 11));
        welcome.setEditable(false);

        Button btnStart = new Button("Next Move");
        btnStart.setFocusable(false);



        tiles = new TetrisSquares(TetrisBoard.BOARD_WIDTH, height);

        c = new Container();
        c.setLayout(new BorderLayout());
        c.add(welcome, BorderLayout.NORTH);
        c.add(tiles);
        c.add(btnStart,BorderLayout.SOUTH);

        btnStart.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e)
           {
             tiles.removeAll();
             tiles.revalidate();
           }
        });


        final Container main = new Container();

        main.setLayout(new GridLayout(1, 2));
        display.add(c);



        display.pack();

        display.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        display.setVisible(true);
    }

    public ArrayList<ArrayList<Color>> getBoard() {
        return colours;
    }

    public void setColor(ArrayList<ArrayList<Integer>> grid) {
        ListIterator<Integer> li;

        for (int i = 0; i < width; i++) {
            colours.add(new ArrayList<Color>());
            li = grid.get(i).listIterator();
            for (int j = 0; j <= height; j++) {
                int n = 0;
                if(li.hasNext()) {
                    n = li.next();

                }
                switch (n) {
                case 1:
                    colours.get(i).add(Color.red);
                    break;
                case 2:
                    colours.get(i).add(Color.pink);
                    break;
                case 3:
                    colours.get(i).add(Color.orange);
                    break;
                case 4:
                    colours.get(i).add(Color.yellow);
                    break;
                case 5:
                    colours.get(i).add(Color.green);
                    break;
                case 6:
                    colours.get(i).add(Color.cyan);
                    break;
                case 7:
                    colours.get(i).add(Color.blue);
                    break;
                default:
                    colours.get(i).add(Color.gray);
                    break;
                }
            }
        }
    }



    public class TetrisSquares extends JPanel {

        public int width;
        public int height;

        public TetrisSquares(int width, int height) {
            this.width = width;
            this.height = width;
            this.setPreferredSize(new Dimension(width * 20, height * 20));
        }

        public void redraw() {
            removeAll();
            //add your elements
            //revalidate();
            //repaint();
        }


        public void paintComponent(Graphics g) {

            super.paintComponent(g);

            Graphics2D graphics = (Graphics2D) g;
            graphics.setColor(Color.BLACK);
            /*
             * tiles.width = getSize().width / width; tiles.height =
             * getSize().height / 800;
             * 
             * insets.left = (getSize().width - width * tiles.width) / 2;
             * insets.right = insets.left; insets.top = 0; insets.bottom =
             * getSize().height - height * tiles.height;
             */
            Dimension size = getSize();
            Insets insets = getInsets();

            int w = size.width - insets.left - insets.right;
            int h = size.height - insets.top - insets.bottom;

            int tileWidth = w / width;
            int tileHeight = w / width;

            ListIterator<Color> li;

            for (int i = 0; i < width; i++) {
                li = colours.get(i).listIterator();
                int n = 20;

                while(li.hasNext()) {
                    --n;
                    int x = (int) (i * tileWidth);
                    int y = (int) (n * tileHeight);
                    graphics.setColor(li.next());
                    graphics.fillRect(x, y, tileWidth, tileHeight);
                    graphics.setColor(Color.black);
                    graphics.drawRect(x, y, tileWidth, tileHeight);
                }
            }

        }

    }

}
Was it helpful?

Solution

Start by having a read through Painting in AWT and Swing to gain a better understanding of the painting system.

removeAll removes all the child components from the container, this isn't really going to help you in this situation...

revalidate deals with the layout subsystem and updating the container hierarchy in response to changes in the container contents, again, not really going to help...

In you paintComponent method, you are referencing a ArrayList called colours, which is used paint the squares. You need to reset this list to stop the paintComponent method from filling in the colors

Your redaw method should look more something like...

public void redraw() {
    colours.clear();
    repaint();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top