Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java清除具有透明背景的JPanel_Java_Swing_Graphics_Jpanel_Transparent - Fatal编程技术网

java清除具有透明背景的JPanel

java清除具有透明背景的JPanel,java,swing,graphics,jpanel,transparent,Java,Swing,Graphics,Jpanel,Transparent,我一直在尝试创建一个屏幕保护程序。本质上,屏幕上有多个圆圈。但是,当我使背景透明时,我不能再使用clearRect(),因为这将强制背景为白色。有没有办法在保持背景透明的同时清除已绘制的圆 class ScreenSaver extends JPanel implements ActionListener { static Timer t; Ball b[]; int size = 5; ScreenSaver() { Random rnd = new Random(); b

我一直在尝试创建一个屏幕保护程序。本质上,屏幕上有多个圆圈。但是,当我使背景透明时,我不能再使用clearRect(),因为这将强制背景为白色。有没有办法在保持背景透明的同时清除已绘制的圆

class ScreenSaver extends JPanel implements ActionListener {
static Timer t;
Ball b[];
int size = 5;

ScreenSaver() {
    Random rnd = new Random();
    b = new Ball[size];
    for (int i = 0; i < size; i++) {
        int x = rnd.nextInt(1400)+100;
        int y = rnd.nextInt(700)+100;
        int r = rnd.nextInt(40)+11;
        Color c = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
        int dx = rnd.nextInt(20)-10;
        if (dx == 0)
            dx++;
        int dy = rnd.nextInt(20)-10;
        if (dy == 0)
            dy++;

        b[i] = new Ball(x, y, r, c, incR, incG, incB, dx, dy);
    }
}
public void actionPerformed(ActionEvent e) {
    repaint();
}
public void paintComponent(Graphics g) {
    //g.clearRect(0, 0, 1600, 900);

    for (int i = 0; i < size; i++) {
        if (b[i].x + b[i].r+b[i].dx >= 1600)
            b[i].dx *= -1;
        if (b[i].x - b[i].r+b[i].dx <= 0)
            b[i].dx *= -1;
        if (b[i].y + b[i].r+b[i].dy >= 900)
            b[i].dy *= -1;
        if (b[i].y - b[i].r+b[i].dy <= 0)
            b[i].dy *= -1;

        b[i].x += b[i].dx;
        b[i].y += b[i].dy;

        g.fillOval(b[i].x-b[i].r, b[i].y-b[i].r, b[i].r*2, b[i].r*2);
    }        
}
}
class Painter extends JFrame{
Painter() {
    ScreenSaver mySS = new ScreenSaver();
    mySS.setBackground(new Color(0, 0, 0, 0)); //setting the JPanel transparent
    add(mySS);

    ScreenSaver.t = new Timer(100, mySS);
    ScreenSaver.t.start();

    setTitle("My Screen Saver");
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setLocationRelativeTo(null);
    setUndecorated(true);
    setBackground(new Color(0, 0, 0, 0)); //setting the JFrame transparent
    setVisible(true);
}
}
类屏幕保护程序扩展JPanel实现ActionListener{
静态定时器t;
球b[];
int size=5;
屏幕保护程序(){
随机rnd=新随机();
b=新球[尺寸];
对于(int i=0;i=1600)
b[i].dx*=-1;
if(b[i].x-b[i].r+b[i].dx=900)
b[i].dy*=-1;

如果(b[i].y-b[i].r+b[i].dy,则不要在Swing组件中使用基于alpha的颜色,只需使用
setOpaque(false)

改变

mySS.setBackground(new Color(0, 0, 0, 0));

Swing只知道如何绘制不透明或透明组件(通过
不透明
属性)


作为个人偏好,在进行任何自定义绘制之前,您还应该调用
super.paintComponent
,因为您的
paintComponent
确实应该对状态做出假设

永远不要从绘制方法调用repaint()。它将触发对绘制和paintComponent的另一个调用(最终),创建一个无休止的循环。另外,不要直接调用paintComponent,也不要创建自己的图形。系统会执行这些操作。您的actionPerformed方法应该调用repaint()没有别的了。@VGR谢谢。做了这些更改,效果更好。但仍然没有清除已经绘制的圆。你说的背景透明是什么意思?我在你的代码中没有看到它。@user3437460 mySS.setBackground(新颜色(0,0,0,0));设置JPanel透明和setBackground(新颜色(0,0,0,0));将JFrame设置为透明。第四个参数是alpha级别,根据我所读的内容,通过将其设置为0,可以使两者完全透明,而不会影响JPanel中绘制的内容。是的!这正是我希望的工作方式。我猜我可以离开JFrame
setBackground(新颜色(0,0,0,0))
它是这样的,因为它没有
setOpaque()
选项?(而且它可以工作…)还有,你建议我把
super.paintComponent
放在哪里?Windows是唯一可以使用基于alpha的颜色的Swing组件(是的,这并不令人困惑).就我个人而言,我总是先打电话给
super.paintComponent
,除非我有一个非常非常好的理由去做其他事情好的,谢谢你的洞察力。我问把它放在哪里的唯一原因是因为VGR评论了我最初的问题,说我不应该创建自己的图形,我只有一个地方可以传递给
super.paintComponent
在paintComponent方法中,他还说我不应该这样做,因为它会无限循环。
mySS.setOpaque(false)