Erschwindelte Transparanz mit Robot

schnuffie

Erfahrenes Mitglied
Hallo Experten,

nachdem ich schon mal nach Transparenz suchte und trickreiche Antworten fand, probierte ich es selbst.

Ich erstelle eine Komponente auf einem JFrame, die Hinweise anzeigt. Den kompletten Hintergrund lasse ich dabei durch einen Robot "fotografieren", damit es so aussieht, als ob der JFrame durchsichtig ist. Bei jedem Verschieben wird der passende Teil des Hintergrunds in der "paint(...)"-Methode gezeichnet. Das klappt auch wunderbar und schnell, als ob man mit einer Lupe über den Bildschirm fährt:

Code:
package swing;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
 
public class TransparentFrame extends JFrame implements ComponentListener {
  
  private Robot robot;
  private BufferedImage imgBackground;
  public static void main(String args[]) {
    new TransparentFrame(200, 70, false);
  }
  public TransparentFrame(int width, int height, boolean withoutBorder) {
    super();
    try {
      this.robot = new Robot();
    } catch (AWTException ae) {
      // nichts tun
    }
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(width, height);
    this.setUndecorated(withoutBorder);
    this.copyBackground();
    this.addComponentListener(this);
    this.setVisible(true);
  }
  
  private void copyBackground() {
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    Rectangle rect = new Rectangle(0, 0, d.width, d.height);
    this.imgBackground = robot.createScreenCapture(rect);
    MediaTracker mt = new MediaTracker(this);
    mt.addImage(imgBackground, 0);
    try {
      mt.waitForAll();
    } catch (InterruptedException ie) {
      // nichts tun
    }
  }
  
  public void paint(Graphics g) {
    Point p = this.getLocation();
    Dimension d = this.getSize();
    Image imgViewableBackground = imgBackground.getSubimage(p.x, p.y, d.width, d.height);
    g.drawImage(imgViewableBackground, 0, 0, d.width, d.height, this);
    g.drawString("Mein Name ist Hase", 50, 50);
  }
  
  public void componentResized(ComponentEvent ae) {
    this.invalidate();
    this.repaint();
  }
  public void componentMoved(ComponentEvent ae) {
    this.componentResized(ae);
  }
  public void componentShown(ComponentEvent ae) {
  }
  public void componentHidden(ComponentEvent ae) {
  }
}

Das Problem ist, wenn ich die Größe ändere, wird der Hintergrund grau. Wenn ich ein anderes Fenster öffne, stimmt der Hintergrund nicht mehr.

Meine Lösungsansätze waren:
1. Jedes Mal den Hintergrund neu "fotografieren" = die Anzeige ist schon da, jedoch der Robot noch nicht fertig, Hintergrund wieder grau
2. Mit dem FocusListener arbeiten, beim Aktivieren neu "fotografieren" lassen = gleiches Problem wie bei 1.

Kann man denn nicht einfach den Hintergrund transparent machen? Die "setOpaque(...)"-Methode klappt beim JFrame nicht, da passiert einfach nichts.

Der transparente Hinweis-Dialog soll sowohl auf Windows- als auch auf Linux-Systemen funktionieren. Deshalb habe ich Swing in die engere Wahl genommen.

Hat Jemand eine zündende Idee, wie ich mein Problem lösen kann?
 
Zurück