在未修饰的 JFrame 中支持 Windows-Left 和 Windows-Right

Posted

技术标签:

【中文标题】在未修饰的 JFrame 中支持 Windows-Left 和 Windows-Right【英文标题】:Support for Windows-Left and Windows-Right in undecorated JFrames 【发布时间】:2014-11-30 22:58:25 【问题描述】:

我使用带有自定义标题栏和自定义大小调整器的未装饰 JFrame。一切正常,但是当我制作未装饰的 JFrame 时,我失去了对 Windows-Left/Right 键绑定的支持(似乎它是由 Windows 本机实现的)。我想为我的应用程序重新实现此功能。我的问题:我可以在按键侦听器中检测是否按下了 Windows 键,但我无法检测到另一个键(在我的情况下为左/右)是否与 Windows 键一起按下(InputEvent 中没有修饰符 WINDOWS_MASK_DOWN)。可能有人知道解决方法?

这是我的代码:

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class HeadlessFrameTest 

    public static void main(String[] args) 
        final JFrame frm = new JFrame("Test");
        final JTextField field = new JTextField();
        frm.add(field, BorderLayout.NORTH);
        field.addKeyListener(new KeyAdapter() 
            @Override
            public void keyPressed(KeyEvent e) 
                System.out.println(e);
            
        );
        frm.setUndecorated(true);
        frm.setSize(500, 550);
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setVisible(true);
    


【问题讨论】:

+1 (no modifier WINDOWS_MASK_DOWN in InputEvent). 按下右/左键时(在 JDK7 中)甚至不会生成任何事件,尽管为 keyReleased 事件生成了一个事件。这告诉我 Windows 正在拦截该事件。奇怪的是,左右键功能不起作用,因为 Windows+Up 键确实最大化了窗口,尽管 Windows+Down 不会恢复窗口。所以肯定有矛盾。我不知道解决方案。 这方面有什么更新吗?我遇到了同样的问题,正在寻找解决方案。 【参考方案1】:

好吧,我无法像在我的系统上那样正确测试它,Windows+LeftRight 即使是未修饰的帧也会被 Windows 拦截和处理,但是为未使用的组合 Windows+A 添加另一种情况证明,如果主机系统不使用以下代码,则以下代码有效快捷键:

(更新:由于它似乎是 Windows 消耗的按键事件,因此 Windows+LeftRight 的按键释放可以被抓)

final JFrame frm = new JFrame("Test");
final JTextField field = new JTextField();
frm.add(field, BorderLayout.NORTH);
frm.getToolkit().addAWTEventListener(new AWTEventListener() 
    boolean winDown;
    public void eventDispatched(AWTEvent event) 
        KeyEvent ev=(KeyEvent)event;
        final boolean pressed = ev.getID()==KeyEvent.KEY_PRESSED;
        if(ev.getKeyCode()==KeyEvent.VK_WINDOWS) winDown=pressed;
        else if(winDown) switch(ev.getKeyCode()) 
            case KeyEvent.VK_LEFT:
                System.out.println("windows + LEFT "+(pressed?"pressed":"released"));
                break;
            case KeyEvent.VK_RIGHT:
                System.out.println("windows + RIGHT "+(pressed?"pressed":"released"));
                break;
            case KeyEvent.VK_A:
                System.out.println("windows + A "+(pressed?"pressed":"released"));
                break;
        
    
, KeyEvent.KEY_EVENT_MASK);
frm.setUndecorated(true);
frm.setSize(500, 550);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setVisible(true);

似乎组件上的普通键监听器不起作用,因为当按下 Windows 时组件失去焦点。

【讨论】:

感谢您的回答,但您的建议不起作用(至少在我的 Windows 计算机上)。 win+arrow 甚至win + A 都不起作用?恐怕,Windows 正在拦截 win+arrow 组合键,即使它们不起作用。但是win + A 确实在我的机器 win7 以及 jdk7 和 jdk8 上工作。因此,恐怕这是您能得到的最接近的东西,换句话说,如果这不起作用,就没有解决方案。 Windows+A 有效,但我的目标是 Windows+ArrowLeft/Right,因为用户知道这些键。 好的,我更新了代码以对密钥释放做出反应。如果您可以让程序在释放左/右键时做出反应,那么您就有了解决方案。否则,我们无能为力(除了向 Oracle 提交功能请求)。也许真正的问题是为什么 win+left 和 win+right 不起作用? 是的。这就是问题所在。我将发布 AWT 的 RFE。甲骨文应该可以实现吧。

以上是关于在未修饰的 JFrame 中支持 Windows-Left 和 Windows-Right的主要内容,如果未能解决你的问题,请参考以下文章

java形式的未修饰jframe中的Java相对定位swing组件

拖动未修饰的 jDialog

Java中如何设置在JFrame中控件的位置和大小

为啥我的 JScript(Windows 脚本宿主)在未捕获的异常中以 0 退出?

java中如何在jframe标题栏中添加按钮

如何在未安装Visual Studio的计算机上安装Windows服务?