2016-05-03 52 views
1

我一直在試圖創建一個屏幕保護程序。基本上,有多個圍繞屏幕的圓圈。但是,當我使背景透明時,我無法再使用clearRect(),因爲這會強制背景爲白色。有什麼方法可以在保持背景透明的同時清除已繪製的圓圈?java清除透明背景的JPanel

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); 
} 
} 
+1

不要調用重繪()從一個paint方法,直到永遠。它將觸發另一個調用來繪製paintComponent(最終),創建一個無限循環。另外,不要直接調用paintComponent,也不要創建自己的Graphics。系統做這些事情。你的actionPerformed方法應該調用repaint()而不是別的。 – VGR

+0

@VGR謝謝。使這些變化和工作更好。仍然不清除已經繪製的圓圈。 – MrE

+0

通過設置背景透明是什麼意思?我沒有在你的代碼中看到它。 – user3437460

回答

2

不要使用基於alpha的顏色與Swing組件,只需使用setOpaque(false)

變化

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

mySS.setOpaque(false) 

搖擺只知道怎麼畫不透明或透明組件(通過opaque屬性)

由於個人喜好,你也應該打電話super.paintComponent你做任何自定義塗裝前,作爲您paintComponent有關國家真正應該做的假設

+0

是的!這正如我所希望的那樣工作。我猜我可以離開JFrame'setBackground(new Color(0,0,0,0));'這是因爲沒有'setOpaque()'選項嗎? (它的工作原理...)另外你在哪裏建議我把'super.paintComponent'? – MrE

+1

Windows是唯一的Swing組件,你可以使用基於alpha的顏色(是的,這並不令人困惑)。就個人而言,我總是先打電話給'super.paintComponent',除非我有一個非常非常好的理由去做 – MadProgrammer

+0

好的,謝謝你的洞察力。我問這個問題的唯一原因是因爲VGR評論我的原始問題,說我不應該創建自己的圖形,並且我有一個圖形g,我可以傳遞給'super.paintComponent'的唯一地方是在paintComponent方法中,他也說過我不應該這樣做,因爲它會無限循環。 – MrE