Search code examples
javajframetransparentpaintcomponent

JFrame loses transparency trait once components added


I want to make an overlay window that has a transparent frame with non transparent children. I was successful when making the transparent window and even was successful when adding a test child to see if it work. But as soon as I replace that test code with my paintComponent... I get a white background. Anyone know why?

package blahh;

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

public class LoadingFrame {

    public static void main(String[] args) {
        LoadingFrame Class = new LoadingFrame();
        Class.frameChar();


    }

    public void frameChar(){
        JFrame frame = new JFrame();
        B b = new B();


        frame.setUndecorated(true);
        frame.setBackground(new Color(0, 0, 0, 0));
        frame.setAlwaysOnTop(true);    
        frame.setPreferredSize(new Dimension(500, 500));
        frame.getContentPane().setLayout(new java.awt.BorderLayout()); 
        frame.setLocationRelativeTo(null);        
        frame.setVisible(true);
        //frame.getContentPane().add(new JLabel("test code");
        frame.add(b);
        frame.pack();
    }

 public class B extends JPanel{
     public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawRect(0, 0, 100, 100);


        }

 }   
}

Solution

  • JPanel is opaque by default, combined with BorderLayout, this will make it cover the entire frame, making it appear opaque. You need to call setOpaque(false) on it to make it see through

        JFrame frame = new JFrame();
        B b = new B();
        b.setOpaque(false);
    
    
        frame.setUndecorated(true);
        frame.setBackground(new Color(0, 0, 0, 0));
        frame.setAlwaysOnTop(true);    
        // I'd prefer to override getPreferredSize of B
        frame.setPreferredSize(new Dimension(500, 500));
        frame.setLocationRelativeTo(null);        
        frame.add(b);
        frame.pack();
        frame.setVisible(true);
    

    ps- You should also call setVisible last where possible, it just reduces the possibility of your components not showing up randomly