简体   繁体   中英

Swing - How do I make a transparent JFrame with opaque content?

My goal is to have a transparent JFrame with a non-transparent JPanel that is constantly drawing a square at a random place

private static final int alpha = 255;

public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);

    frame.setUndecorated(true);
    frame.setBackground(new Color(255, 255, 255, alpha));

    CustomPanel panel = new CustomPanel();

    panel.setBackground(new Color(255, 255, 255, 0));

    new Timer().schedule(new TimerTask() {

        @Override
        public void run() {

            panel.revalidate();
            panel.repaint();

        }

    }, 0, 1000);

    frame.add(panel);

    frame.setVisible(true);

}

public static class CustomPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.clearRect(0, 0, getWidth(), getHeight());
        g.setColor(new Color(0, 255, 0));
        g.fillRect((int)(Math.random() * 380), (int)(Math.random() * 320), 20, 20);
    }

}

Currently, the frame is rendered with a white background and the square is drawn correctly.

alpha = 255

在此处输入图片说明

However, if I reduce alpha to 31, clearRect will not clear the JFrame background and it will start overlapping itself

alpha = 31 , 1 Iteration vs. 4 Iterations

在此处输入图片说明

As time goes on, the background will become more opaque as more copies are rendered over it.

For a transparent panel don't use a transparent color. Swing does not paint backgrounds with transparency correctly. See Background With Transparency for more information.

However, for full transparency there is a simple solution. Just make the panel transparent:

//panel.setBackground(new Color(255, 255, 255, 0));
panel.setOpaque( false );

Then in the painting code you would use:

super.paintComponent(g);
g.setColor(new Color(0, 255, 0));
g.fillRect((int)(Math.random() * 380), (int)(Math.random() * 320), 20, 20);

Note however you should NOT be using random values in a painting method. You can't control when or how often Swing will repaint a component.

Instead you need a property of the class to be the Color for the Rectangle. Then you need a method like setSquareColor(...) when you want to change the Color of the square.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM