2016-05-03 13 views
1

Ich habe versucht, ein Bildschirmschoner-Programm zu erstellen. Im Wesentlichen gibt es mehrere Kreise, die sich auf dem Bildschirm bewegen. Wenn ich den Hintergrund jedoch transparent mache, kann ich clearErgebnis() nicht mehr verwenden, da der Hintergrund dadurch weiß wird. Gibt es eine Möglichkeit, die bereits gezeichneten Kreise zu löschen, während der Hintergrund transparent bleibt?Java löschen ein JPanel mit einem transparenten Hintergrund

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

Sie repaint nicht nennen() von einem Farbverfahren, immer werden soll. Es löst einen weiteren Aufruf von paintComponent (eventuell) aus und erzeugt eine Endlosschleife. Rufen Sie paintComponent nicht direkt auf und erstellen Sie keine eigenen Grafiken. Das System macht diese Dinge. Ihre actionPerformed-Methode sollte repaint() und sonst nichts aufrufen. – VGR

+0

@VGR Danke. Machte diese Änderungen und es funktioniert besser. Immer noch nicht die bereits gezeichneten Kreise löschen. – MrE

+0

Was meinen Sie, indem Sie den Hintergrund transparent setzen? Ich habe es in deinen Codes nicht gesehen. – user3437460

Antwort

2

nicht alpha basierte Farben mit Swing-Komponenten verwenden, anstatt einfach, verwenden setOpaque(false)

ändern

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

zu

mySS.setOpaque(false) 

Schaukel nur weiß, wie undurchsichtig zu malen oder transparente Komponenten (über die opaque Eigenschaft)

Als persönliche Präferenz, können Sie auch super.paintComponent Aufruf werden sollten, bevor Sie eine benutzerdefinierte Malerei zu tun, als Ihre paintComponent wirklich machen Annahmen über den Zustand

+0

Ja! Das funktioniert genau so, wie ich es mir erhofft hatte. Ich schätze, ich kann die JFrame 'setBackground (neue Farbe (0, 0, 0, 0));' so wie es ist, da es keine 'setOpak()' Option dafür gibt? (und es funktioniert ...) Auch wo schlägst du vor, ich habe die 'super.paintComponent'? – MrE

+1

Windows ist die einzige Swing-Komponente, mit der Sie Alpha-basierte Farben verwenden können (ja, das ist nicht verwirrend). Persönlich würde ich immer 'super.paintComponent' zuerst nennen, es sei denn, ich hätte einen sehr, sehr guten Grund, es anders zu machen. – MadProgrammer

+0

Okay, danke für die Einsicht. Der einzige Grund, warum ich frage, wo ich es hinstellen soll, ist, dass VGR meine ursprüngliche Frage kommentiert hat, dass ich keine eigenen Grafiken erstellen soll und der einzige Ort, an dem ich ein Graphics g an "super.paintComponent" übergeben kann, ist in der paintComponent-Methode, was er auch sagte, war etwas, was ich nicht tun sollte, da es unendlich viele Schleifen geben wird. – MrE