2009-07-27 5 views

Antwort

5

Ich glaube, das wird Ihre Frage beantworten. Um es auszuführen, benötigen Sie Java 6 Update 10 und höher. Getestet habe ich es auf Windows Vista

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ClickThrough { 

    public static void main(String[] args) { 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     JFrame f = new JFrame("Test"); 
     f.setAlwaysOnTop(true); 
     Component c = new JPanel() { 
      @Override 
      public void paintComponent(Graphics g) { 
       Graphics2D g2 = (Graphics2D)g.create(); 
       g2.setColor(Color.gray); 
       int w = getWidth(); 
       int h = getHeight(); 
       g2.fillRect(0, 0, w,h); 
       g2.setComposite(AlphaComposite.Clear); 
       g2.fillRect(w/4, h/4, w-2*(w/4), h-2*(h/4)); 
      } 
     }; 
     c.setPreferredSize(new Dimension(300, 300)); 
     f.getContentPane().add(c); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.pack(); 
     f.setVisible(true); 
     com.sun.awt.AWTUtilities.setWindowOpaque(f,false); 
    } 

} 

Beachten Sie, dass Sie benötigen, um entweder ein undecorated Fenster oder eine, die allein von Java eingerichtet ist (nicht die Standard-OS Dekoration) sonst der Code wird nicht funktionieren.

+0

scheint Click gut mit jdk 1.6, 1.7 auf Windows 7, jdk 1.6, 1.7 auf XP zu ermöglichen. Nicht sicher über andere Betriebssysteme obwohl ... – rogerdpack

+0

Dies ist ein gefährliches Beispiel, wie es versucht, Transparenz auf eine undurchsichtige Komponente zu "fälschen", die Grafik Geisterbilder und andere Grafikartefakte führen könnte. Besser und einfacher wäre es gewesen, das 'Component'' c' transparent zu machen, indem man 'setOpaue' benutzt und es' false' übergibt. Sie haben auch die Farbkette gebrochen – MadProgrammer

0

Sie könnten versuchen, die Roboterklasse http://java.sun.com/javase/6/docs/api/java/awt/Robot.html zu verwenden, mit der Sie Systemereignisse für das Betriebssystem auf niedriger Ebene angeben können, insbesondere Dinge wie Mausereignisse.

+1

Roboter vorbei zur Erzeugung von Systemereignissen verwendet werden, aber wenn mein transparenter Rahmen bereits an der Stelle ist, wo ich klicken muß, würden das nicht der Java-Rahmen erhält das Ereignis erneut? – Varun

+0

können Sie die gerade an der Glasscheibe fangen (lesen Sie das Java-Tutorial dafür) und dann einfach das Ereignis konsumieren. –

+1

Sie können das Fenster vorübergehend ausblenden. es wird etwas flackern, das ich weiß, aber ich kann nicht an etwas anderes denken .... –

2

Savvas 'Antwort hat mir auch auf MacOS X 10.7.3 mit Java 1.6.0_31 perfekt geholfen. Vielen Dank! Das einzige, was: Ich hatte zusätzlich

f.setUndecorated(true); 
+1

Ich fand dies notwendig, um ohne Ausnahmen auf OS X 10.9 mit Java 1.7 zu laufen.0_4, aber der transparente Bereich ** erlaubte keine Klickereignisse ** zu den darunter liegenden Anwendungen. – dpdearing

+0

Dies scheint ein plattformabhängiges Problem zu sein und ist auch unter https://bugs.openjdk.java.net/browse/JDK-8013450 und http://stackoverflow.com/q/13020607/186818 aufgeführt – dpdearing

1

Diese Antwort ist nicht gesetzt, sondern ein Update, das ein Beispiel auch gefährlich Fragen der akzeptierte Antwort korrigiert kompatibel mit Java wie die Bereitstellung 7+

Per-Pixel-Alpharing überprüft jedes Pixel im Fenster, um festzustellen, ob es transparent ist oder nicht. Wenn es transparent ist, können die Mausereignisse passieren, wenn es nicht transparent ist, werden die Mausereignisse vom Fenster erfasst. Dies ist im Allgemeinen ein Problem auf Betriebssystemebene.

Das Beispiel ist, dass Sie tatsächlich einige sehr gefährliche Dinge tun, zuerst ist es eine transluzente Farbe auf eine undurchsichtige Komponente, das bedeutet, dass Swing nicht weiß, dass es tatsächlich etwas unter der Komponente malen sollte und auch dazu führen könnte In einer Reihe von sehr unangenehmen Farbartefakten, da Swing nur über undurchsichtige und transparente Komponenten weiß, weiß es nichts über semitransparente Komponenten, daher müssen Sie die API austricksen.

Bei der benutzerdefinierten Bemalung sollten Sie immer super.paintComponent anrufen, um sicherzustellen, dass der Graphics-Kontext vor dem Bemalen korrekt eingerichtet ist. In Ihrem Fall sollten Sie auch die Komponente transparent machen setOpaque verwenden und es false

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestFrame { 

    public static void main(String[] args) { 
     new TestFrame(); 
    } 

    public TestFrame() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setUndecorated(true); 
       frame.setAlwaysOnTop(true); 
       frame.setBackground(new Color(0, 0, 0, 0)); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setOpaque(false); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setColor(Color.BLUE); 
      g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
      g2d.fill(new Rectangle(0, 0, getWidth(), getHeight())); 
      g2d.dispose(); 
     } 

    } 

}