在 Windows 下禁用 JFrame 中的默认 ALT 键操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1722864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:25:58  来源:igfitidea点击:

Disable default ALT key action in JFrame under Windows

javawindowsswing

提问by Bart Kiers

I would like to let my JFrame under Windows notact upon an ALTkey press. To clarify, when you execute the following snippet of code:

我想,让我在Windows下的JFrame经的行为ALT按键。澄清一下,当您执行以下代码片段时:

import javax.swing.*;

public class FrameTest {
    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

and press the ALTkey and then the arrow downkey, you get a menu in the upper left corner in which you can choose to minimize, move, close etc. the frame (at least I get that). I would like to disable this: ie. the JFrame should not "listen" to these ALTpresses.

然后按ALT键,然后按arrow down键,您会在左上角看到一个菜单,您可以在其中选择最小化、移动、关闭框架等(至少我明白)。我想禁用这个:即。JFrame 不应该“听”这些新闻ALT

I believe that certain Windows components react by default on the ALTkey because when I add a menu bar to my frame, and explicitly set the look & feel to the system look & feel, the menu (File) is now automatically selected after pressing the ALTkey:

我相信某些 Windows 组件在默认情况下会对ALT键做出反应,因为当我向框架添加菜单栏,并将外观和感觉明确设置为系统外观时,File现在按下ALT键后会自动选择菜单 ( ) :

import javax.swing.*;

public class FrameTest {
    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("File");
        menuBar.add(menu);
        frame.setJMenuBar(menuBar);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // set Windows look and feel
        frame.setVisible(true);
    }
}

and when I remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())from the example above, this behaviour is not exhibited when pressing the ALTkey: the menu is not selected, but the JFrame is.

当我UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())从上面的示例中删除时,按下该ALT键时不会出现此行为:未选择菜单,但 JFrame.

When no look & feel is set, the "Metal" look and feel is used. It is clear by looking at the menu bar in my previous example that you go from "native look"to "Metal look"when you remove UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())from the code. However, I don't see a change in the JFrame, no matter what look & feel I set, it always looks like a native Windows frame.

如果未设置外观和感觉,则使用“金属”外观和感觉。通过查看我上一个示例中的菜单栏可以清楚地看出,当您从代码中删除时,您会从“本机外观”变为“金属外观”UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())。但是,我没有看到 JFrame 有任何变化,无论我设置什么外观和感觉,它总是看起来像一个原生的 Windows 框架。

So, my question is: how can I disable this ALTbehaviour on my JFrame? I guess I can do it by actually changing the look and feel of the JFrame. Is that possible? If so, how?

所以,我的问题是:如何ALT在 JFrame 上禁用此行为?我想我可以通过实际更改 JFrame 的外观来实现。那可能吗?如果是这样,如何?

Thanks!

谢谢!

采纳答案by Joey

Actually, what you are seeing here is pretty much outside your nice, Swing-y Java world. The window frame (except for MDI interfaces) will alwaysbe drawn by the window manager of the underlying operating system. And that's also the reason why the Altkey behaves like you observe. This key is intercepted by the WM in this case and it decides that you want to bring up the system menu of the program. That's totally unrelated to Java.

实际上,您在这里看到的内容几乎超出了您美好的 Swing-y Java 世界。窗口框架(MDI 接口除外)将始终由底层操作系统的窗口管理器绘制。这也是Alt密钥行为像您观察到的那样的原因。在这种情况下,该键被 WM 截获,并决定您要调出程序的系统菜单。这与Java完全无关。

For several reasons you can't change the "look and feel" of the window frame, the main one being that this is outside Swing's PLAF system. You can remove the window frame, leaving behind a naked window (freezing in the cold November wind), then you also shouldn't get a system menu anymore.

出于多种原因,您无法更改窗框的“外观和感觉”,主要的原因是它在 Swing 的 PLAF 系统之外。您可以移除窗框,留下一个裸露的窗户(在 11 月的寒冷风中冻结),然后您也不应该再获得系统菜单。

Furthermore you could try handling the Altkeypress and not delegating that very keypress further (the application gets it before the WM does, so you canmess with these things). My Java-Fu is a little rusty right now, though, so no idea if and how this can be achieved.

此外,您可以尝试处理Alt按键而不是进一步委派该按键(应用程序在 WM 之前获取它,因此您可以弄乱这些东西)。不过,我的 Java-Fu 现在有点生疏,所以不知道是否以及如何实现。

回答by Alex Nikolaenkov

Just for history:

只为历史:

You can do this. Window manger handles all the events to the current keyboard focus manager and it decides what to do with the particular key. Every swing application has only one keyboard focus manager that's why your changes will affect the whole application and not the particular frame. The code below should do the trick:

你可以这样做。窗口管理器处理当前键盘焦点管理器的所有事件,并决定如何处理特定键。每个 Swing 应用程序只有一个键盘焦点管理器,这就是为什么您的更改会影响整个应用程序而不是特定框架的原因。下面的代码应该可以解决问题:

frame.addFocusListener(new FocusListener() {
        private final KeyEventDispatcher altDisabler = new KeyEventDispatcher() {
            @Override
            public boolean dispatchKeyEvent(KeyEvent e) {
                return e.getKeyCode() == 18;
            }
        };

        @Override
        public void focusGained(FocusEvent e) {
            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(altDisabler);
        }

        @Override
        public void focusLost(FocusEvent e) {
            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(altDisabler);
        }
    });

回答by Adam Goode

It sounds like you're hitting upon some default interactions with the Windows window manager. It is possible that if you draw your own titlebar and borders that Windows will no longer set these default handlers on the Alt key.

听起来您正在与 Windows 窗口管理器进行一些默认交互。如果您绘制自己的标题栏和边框,Windows 可能不再在 Alt 键上设置这些默认处理程序。

You might want to try Substance, which gives you much more control over these sorts of things, while still working with the standard Swing components.

您可能想尝试Substance,它使您可以更好地控制这些类型的事情,同时仍然使用标准 Swing 组件。

Or, try this before you make your frame visible:

或者,在使框架可见之前尝试此操作:

JFrame.setDefaultLookAndFeelDecorated(true);