Search code examples
javajframejpanelpaintrepaint

Adding JPanel to JLayeredPane causes paint() method to not get called


To provide some background info that might help, I am creating the game pong and I decided to add an escape/pause menu (when you press escape on the keyboard a menu pops up with some settings), I looked around and found that the best way to do this is to use JLayeredPane and add another JPanel on top. However, when I added my 'painter' class to the JLayeredPane, the paint(Graphics g) method stopped getting called (it worked fine when I just added it to the JFrame).

import javax.swing.*;

public class Game extends JFrame {

    public static Painter painter;

    public Game() {
        setSize(500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLayeredPane lp = getLayeredPane();

        painter = new Painter();

        add(lp);
    }

    public static void main(String[] args) {
        Game frame = new Game();
        frame.setVisible(true);
        painter.repaint();
    }

}

And here is my Painter class

import java.awt.*;
import javax.swing.*;

public class Painter extends JPanel {

    public void paint(Graphics g) {
        System.out.println("Working");
        super.paint(g);
    }

}

Instead of add(lp);, I originally tried lp.add(painter); in which case the paint method never got called. By doing add(lp) I get an IllegalArgumentException for adding container's parent to itself.


Solution

  • Here is mcve of using LayeredPane :

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JLayeredPane;
    import javax.swing.JPanel;
    
    public class Game extends JFrame {
    
        public Game() {
            setSize(250, 150);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JLayeredPane lp = getLayeredPane();
            //assign layout manager. otherwise you need to set content
            //bounds (not recommended)
            lp.setLayout(new BorderLayout());
            Painter painter = new Painter();
            lp.add(painter,1);
        }
    
        public static void main(String[] args) {
            Game frame = new Game();
            frame.setVisible(true);;
        }
    }
    
    class Painter extends JPanel {
    
        @Override
        protected void paintComponent(Graphics g) { //do not override paint
            super.paintComponent(g);
            g.drawString("Working",50,50);
        }
    }