9

リモートデスクトップ/VNCクライアントのようなものを開発しようとしています。クライアント ウィンドウですべてのイベントをキャプチャする必要があります。私が使用している方法は、のprocessEventメソッドをオーバーライドすることですJFrame:

@Override
protected void processEvent(AWTEvent e) {
    ...
}

ただし、WindowsキーやAlt+Tabウィンドウなどのイベントでは非アクティブになっています。

...    
00000191 KEY_PRESSED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c 
00000192 KEY_RELEASED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c 
000000ce WINDOW_DEACTIVATED,opposite=null,oldState=0,newState=0 
...

このようなイベントでウィンドウをアクティブに保つにはどうすればよいですか?

これよりも純粋なJavaソリューションをお勧めします純粋なJavaソリューションがない場合、誰かがJNAソリューション(またはその事実に対する他のソリューション)を教えてもらえますか?

EDIT1: * ウィンドウの非アクティブ化に対するあいまいな用語「フォーカス」を解決しました * 非純粋な Java ソリューションが受け入れられることを強調しました

4

4 に答える 4

1

1.) JNAには、あなたが望むほとんどのことを行う例が付属しています:

http://java.net/projects/jna/sources/svn/content/trunk/jnalib/contrib/w32keyhook/KeyHook.java

CallNextHookExキーをブロックするには、 -cfを呼び出す代わりに 1 を返すだけです。MSDNドキュメント

2.) JNativeHookを使用すると、グローバル イベント処理にフックできますが、現時点では、イベントの配信を停止する方法はありません。たとえば、Windows キーは依然としてスタート メニューをアクティブにします。ただし、オーバーヘッドがはるかに少ないため、検討する価値はあります。また、必要に応じて動作するように変更することもできます (ここから始めCallNextHookEx ます)。ただし、GPLの下でライセンスされています。

3.) これを行うもう 1 つのクリーンな方法は、SWT に切り替えて、SWT Win32 拡張機能を使用してキーボード イベントをインターセプトすることです。

于 2012-12-21T20:57:43.947 に答える
1

JFrame は Window からそのメソッドを継承するため、ウィンドウを常にフォーカス可能 ( Window.setFocusableWindowState ) に設定することはできません。次のような簡単なもの: window.setFocusableWindowsState(true). そして、キーイベントリスナー内でこれを呼び出します: (このコードは変更されていますが、元はUnresponsive KeyListener for JFrameからのものです)

public class MyFrame extends JFrame { 

    private class MyDispatcher implements KeyEventDispatcher 
    {
        private JFrame frame;

        public MyDispatcher(JFrame jf)
        {
            this.frame = jf;
        }

        public boolean dispatchKeyEvent(KeyEvent e) 
        {
            frame.setFocusableWindowState(true);
            return false;
        }
    }

    public MyFrame() 
    {
        add(new JTextField());
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher(this));
    }

    public static void main(String[] args) 
    {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}

このコードをテストすることはできませんでしたが、少なくともこのアイデアが正しい方向に進んでいることを願っています.

于 2012-12-20T16:36:50.587 に答える
0

カスタム FocusManager を設定し、dispatchEvent メソッドをオーバーライドするか、Toolkit.getDefaultToolkit().addAWTEventListener(..) を使用できます。ただし、これは OS がキャッチした keyEvents をキャッチしませんが、ツールキットに登録すると、repaint などのイベントを取得できます。

于 2012-12-15T23:31:20.080 に答える
0

WindowListener を使用できます。これがイベントのキャプチャに役立つことを願っています。windowfocuslistener、windowstatelistener もあります。

public class WindowListenerImpl implements WindowListener(){
     @Override
                        public void windowOpened(WindowEvent windowevent) {
                           //urs windowevent to get source.

                        }

                        @Override
                        public void windowIconified(WindowEvent windowevent) {
                           //urs windowevent to get source.

                        }

                        @Override
                        public void windowDeiconified(WindowEvent windowevent) {
                            //urs windowevent to get source.

                        }

                        @Override
                        public void windowDeactivated(WindowEvent windowevent) {

                             //urs windowevent to get source.
                        }

                        @Override
                        public void windowClosing(WindowEvent windowevent) {
                           //urs windowevent to get source.

                        }

                        @Override
                        public void windowClosed(WindowEvent windowevent) {
                             //urs windowevent to get source.

                        }

                        @Override
                        public void windowActivated(WindowEvent windowevent) {
                           //urs windowevent to get source.

                        }
    public WindowEvent{
    public static void main(String[] args){
    WindowListenerImpl  listenerImpl=new WindowListenerImpl ();
    new JFrame.addWindowListener(listenerImpl);
    }
于 2012-12-21T11:38:05.610 に答える