我正在尝试开发远程桌面/VNC客户端之类的东西。我有必要捕获客户端窗口中的所有事件。我正在使用的方法是覆盖JFrame
的processEvent
方法:
@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解决方案(或任何其他解决方案)吗?
编辑1:* 解决了窗口停用的歧义术语"焦点"* 强调非纯Java解决方案是可以接受
1.) JNA 附带了一个示例,几乎可以满足您的需求:
http://java.net/projects/jna/sources/svn/content/trunk/jnalib/contrib/w32keyhook/KeyHook.java
为了阻止密钥,只需返回 1 而不是调用 CallNextHookEx
- 参见 MSDN 文档。
2.) JNativeHook 允许您挂接到全局事件处理,但现在无法阻止事件被传递 - 例如 Windows 键仍将激活开始菜单。但是,它仍然值得一看,因为它的开销要少得多,您可以对其进行修改(从此处的CallNextHookEx
开始)以按照您想要的方式运行。不过,它是GPL下的许可证。
3.) 另一种干净的方法是切换到 SWT 并使用 SWT Win32 扩展来拦截键盘事件。
您能否不将窗口设置为始终可聚焦(Window.setFocusableWindowState),因为 JFrame 确实从 Windows 继承了该方法。像这样简单的东西:window.setFocusableWindowsState(true)
.在关键事件侦听器中调用以下内容:(此代码已修改,但最初来自 JFrame 的无响应 KeyListener
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);
}
}
我没有测试这段代码,但我希望至少这个想法能让你朝着正确的方向前进。
您可以设置自定义 FocusManager 并覆盖 dispatchEvent 方法或使用 Toolkit.getDefaultToolkit().addAWTEventListener(..)。但是,这不会捕获操作系统捕获的 keyEvents,但如果您在工具包中注册,您仍然会收到重绘等事件。
您可以使用 WindowListener.希望这将有助于捕获事件。也有窗口焦点监听器,窗口状态监听器。
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);
}