2017-08-20 1 views
0

私は、MacOS用のJava/Swingアプリケーションを実装していますが、ウィンドウがアクティブになるまでほとんどのマウスボタンに関連する動作が無効になるのが一般的です。言い換えると、マウスボタンが非アクティブなウィンドウ上で押されると、そのウィンドウはアクティブにされますが、何も起こりません。 (例外があります。クリックすると、ウィンドウがアクティブになり、通常のアクションも実行されます)。これを行う方法はありますか?基本的な問題は、アプリケーションがマウスで押されたイベントを取得するまでに、ウィンドウがすでにアクティブであることです。これまで私が考えていたのは、完全に信頼性がないかもしれないウィンドウ起動イベントとマウス押しイベントを時間で相関させることでした。あなたは)(ボタンのを含んで作ることができるウィンドウがアクティブになるまで無効にするJava/Swingコントロールを実装するにはどうすればよいですか?

+0

あなたはどんな動作を引き出しようとしているのかを100%明確にしているわけではありませんが、JFrameにガラスペインを付け、不透明にして、すべてのマウスアクションをトラップします。 MouseListenerを押すと、ガラスの枠が表示されなくなり( '.setVisible(false)')、マウス操作がJFrameのGUIに到達できるようになります。 –

+0

これは、マウスイベントの動作を抑制する方法の興味深い考えですが、私の問題は、マウスイベントがフレームをアクティブにしたのと同じジェスチャーによって生成されたかどうかを判断する方法です。その場合にのみ、私はその行動を抑制したいのですか? –

答えて

1

が依存するフレームの現在アクティブかどうか:

final JFrame frame = new JFrame(); 

    JButton button = new JButton() { 
     @Override 
     public boolean contains(int x, int y) { 
      return super.contains(x, y) && frame.isActive(); 
     } 
    }; 

フレームが非アクティブであると、ボタンの領域がクリックされた取得するときに含まれているため、ボタンはマウスイベントを受け付けません()戻り値がfalseになると、ボタンの親は、代わりに(そして親の親が返り値がtrueになるまで)contains()を返し、フレームが最後にアクティブになり、ボタンにはマウスのクリックに対する応答が与えられません。

frame.addWindowListener(new WindowAdapter() { 
     private final AWTEventListener awtEventListener = new AWTEventListener() { 
      @Override 
      public void eventDispatched(AWTEvent event) { 
       if (event instanceof MouseEvent && event.getID() == MouseEvent.MOUSE_PRESSED 
         && event.getSource() == button) { 
        ((MouseEvent) event).consume(); 
        frame.toFront(); 

        System.out.println("Special handled"); 
       } 
      } 
     }; 

     @Override 
     public void windowActivated(WindowEvent aE) { 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        Toolkit.getDefaultToolkit().removeAWTEventListener(awtEventListener); 
       } 
      }); 
     } 

     @Override 
     public void windowDeactivated(WindowEvent aE) { 
      Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, MouseEvent.MOUSE_EVENT_MASK); 
     } 
    }); 

アイデア:私は、Mac OSXで動作しませんでした掲示最初の答えは、のは、(適切に処理されないとき、それは壊滅的なことができるので、私は好まない)AWTListenerを使用して解決策を試してみましょうので

+0

............... clever –

+1

私の質問では、マウスイベントが生成され、ディスパッチされるまでに、フレームはすでにアクティブであると言おうとしました。 –

+0

多分、Mac OSXはこれとは異なる動作をしています。私はLinuxでコードをテストして動作しますが、Javaプログラムの場合でもイベント処理がOSごとに矛盾することは珍しくありません:) –

0

私たちはすべてのマウスイベントを傍受し、ボタンのマウスのプレスイベントターゲットに遭遇するとそれを消費し、私たちは人工的にtoFront()を使用してフレームをアクティブにします(私はtoFront() Linuxでも、もう一度呼び出しても問題ありません)。

フレームがアクティブになると、AWTEventListenerを削除した直後にボタンがクリックされないように、invokeLater()を使用してAWTEventListenerの削除が遅延されます。

+0

私は、ここでの問題は、フレームを再アクティブ化するための他の方法があり、そのような場合にマウスイベントが正常に処理されることです。 –

関連する問題