我的目标是要有一个带有不透明JPanel的透明JFrame,该JPanel经常在随机位置绘制一个正方形
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);
}
}
当前,框架以白色背景渲染并且正确绘制了正方形。
但是,如果我将alpha
减少到31,则clearRect
将不会清除JFrame背景,并且会开始重叠自身
随着时间的流逝,随着在其上呈现更多副本,背景将变得更加不透明。
对于透明面板,请不要使用透明颜色。 Swing无法正确绘制透明背景。有关更多信息,请参见Background With Transparency。
但是,要实现完全透明,有一个简单的解决方案。只需使面板透明即可:
//panel.setBackground(new Color(255, 255, 255, 0));
panel.setOpaque( false );
然后在绘画代码中使用:
super.paintComponent(g);
g.setColor(new Color(0, 255, 0));
g.fillRect((int)(Math.random() * 380), (int)(Math.random() * 320), 20, 20);
但是请注意,您不应在绘画方法中使用随机值。您无法控制Swing何时或多久重新绘制一个组件。
相反,您需要类的属性才能成为Rectangle的Color。然后,当您要更改正方形的颜色时,需要使用setSquareColor(...)
之类的方法。