Disable default ALT key action in JFrame under Windows

馋奶兔 提交于 2021-02-07 03:31:45

问题


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

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 ALT key and then the arrow down key, 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 ALT presses.

I believe that certain Windows components react by default on the ALT key 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 ALT key:

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 ALT key: the menu is not selected, but the JFrame is.

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.

So, my question is: how can I disable this ALT behaviour 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?

Thanks!


回答1:


Actually, what you are seeing here is pretty much outside your nice, Swing-y Java world. The window frame (except for MDI interfaces) will always be drawn by the window manager of the underlying operating system. And that's also the reason why the Alt key 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.

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.

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




回答2:


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:

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);
        }
    });



回答3:


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.

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.

Or, try this before you make your frame visible:

JFrame.setDefaultLookAndFeelDecorated(true);


来源:https://stackoverflow.com/questions/1722864/disable-default-alt-key-action-in-jframe-under-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!