2009-07-27 16 views
3

質問はHow to pass mouse events to applications behind mine in C#/Vista?と全く同じですが、私は透過Java UIの場合と同じものが必要です。私は簡単に6.0を使って透明なJava UIを作成することができますが、アプリケーションを介してイベントをアプリケーション(ブラウザなど)に渡すことについての情報は得られませんでした。Java UIの背後にあるアプリケーションにマウスイベントを渡します

答えて

5

これはあなたの質問に答えてくれると思います。これを実行するには、Java 6 update 10以上が必要です。 私は、そうでない場合、コードは動作しませんあなたが装飾のないウィンドウや単体のJava(デフォルト以外のOSの装飾)で飾られているものを持っているいずれかの必要がある注

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

} 

のWindows Vista上でそれをテストしました。

+0

は、jdk 1.6、Windows 7の1.7、JDK 1.6、XPの1.7でよくクリックスルーできるようです。しかし、他のOSについてはわかりません... – rogerdpack

+0

これは危険な例です。不透明なコンポーネントの透明度を "偽造"しようとすると、グラフィックゴーストやその他のグラフィックアーチファクトが発生する可能性があります。私は、 'setOpaue'を使って' Component''c'を透明にし、 'false'を渡すだけで、もっと簡単で良い解決法でした。あなたもペイントチェーンを壊してしまった – MadProgrammer

0

Robot Class http://java.sun.com/javase/6/docs/api/java/awt/Robot.htmlを使用すると、システムイベントを低レベルのオペレーティングシステム、特にマウスイベントなどに指定できます。

+1

を渡す必要がありますjavaフレームは再びイベントを受信しますか? – Varun

+0

あなたはガラスの区画(これについてはJavaのチュートリアルを読んでください)でさえ把握して、単にイベントを消費することができます。 –

+1

一時的にウィンドウを非表示にすることができます。それは私が知っているいくつかのちらつきを紹介しますが、私は他の何かを考えることができません.... –

2

Java 1.6.0_31を使用してMacOS X 10.7.3でSavvasの回答が完全に助けられました。ありがとう! 唯一の事:私はさらにこれが答えではない

f.setUndecorated(true); 
+1

これは、Java 1.7のOS X 10.9で例外なく実行するために必要なものです。0_4ですが、透過領域**ではクリックイベントが**の下のアプリケーションに渡されることは許可されませんでした。 – dpdearing

+0

これはプラットフォームに依存する問題のようであり、https://bugs.openjdk.java.net/browse/JDK-8013450およびhttp://stackoverflow.com/q/13020607/186818にも記載されています。 – dpdearing

1

を設定しなければならなかったが、受け入れ答えに危険な問題を修正するアップデートだけでなく、Javaの7+

と互換性の例を提供しますPer-Pixel alpheringは、ウィンドウ内の各ピクセルをチェックして透明かどうかを判定します。透明であれば、マウスイベントは通過できます。透明でない場合、マウスイベントはウィンドウによって捕捉されます。これは一般的にOSレベルの問題です。

この例では、実際にいくつかの非常に危険なことを行っていますが、最初は不透明なコンポーネントに半透明の色を塗りつぶしています。つまり、コンポーネントの下に何かをペイントする必要があり、スウィングは不透明で透明なコンポーネントのみを知っているため、半透明のコンポーネントについてはわからないため、APIを騙す必要があります。

カスタムペイントを実行するときは、ペイントする前にGraphicsコンテキストが正しく設定されていることを確認するために、常にsuper.paintComponentを呼び出す必要があります。あなたのケースでは、あなたもsetOpaqueを使用してコンポーネントを透明にし、それをロボットがシステムイベントを生成するための私の透明フレームは、私はクリックする必要が場所になっていないでしょうであれば使用することができます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(); 
     } 

    } 

} 
関連する問題