Search code examples
javaswingjpanelgraphics2dmouselistener

Graphics are blocked out when I add a JPanel to the frame (java)


I have some Graphics2D graphics displayed in my frame, and then I added a JPanel to the entire frame so that I can add a mouselistener to clicks anywhere in the panel. However, the graphics disappear, I assume blocked out by the frame. I tried setting the panel to visible false, but that didnt do anything. How can I keep my mouselistener listening on the entire window, and still display my graphics?

EDIT: Heres a bit of code: EDIT:(and some more)

//adding the panel and mouselistener
JPanel allPanel = new JPanel();
allPanel.addMouseListener(this);
frame.add(allPanel);


//...
//drawing some of the graphics
public void draw() {



    frame.add(new CustomPaintComponent());
    // Display the frame

    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setVisible(true);
    JPanel allPanel = new JPanel();
    allPanel.addMouseListener(this);
    frame.add(allPanel);
      }


      static class CustomPaintComponent extends Component {

        private static final long serialVersionUID = 1L;

    public void paint(Graphics g) {

      Graphics2D g2d = (Graphics2D)g;
      g2d.fillRoundRect(10, 10, 50, 50, 10,10);

      //...

Solution

  • Three problems jump out...

    First, JFrame uses a BorderLayout as its default layout manager, this means that only one component can occupy any of its available five positions. By using add(Component) you add each component to the CENTRE position, overriding the first component you added to it...

    Second, JPanel is opaque by default, meaning, even if you did get both components to occupy the same space, the top component would block the lower one

    Third, you should be using paintComponent instead of paint

    Take a look at Performing Custom Painting for more details

    The solution could be to add the MouseListener directly to the custom component

    Another choice would be to use a BorderLayout on the lower component, make the top component transparent (using setOpaque(false)) and add it to the lower component directly...