gpt4 book ai didi

Java Swing如何让JFrame获得焦点

转载 作者:行者123 更新时间:2023-12-04 03:53:02 24 4
gpt4 key购买 nike

我正在开发一个 java swing 应用程序。我希望达到这样的结果:按快捷键让应用程序窗口显示出来。再次按快捷键或单击其他地方让应用程序隐藏。

我用jkeymaster注册监听全局快捷方式的事件,效果不错。但是当用户关注其他窗口时,比如 chrome、office...焦点窗口将是其他应用程序。然后如果用户使用快捷方式。我的应用程序窗口仍会显示,但无法获得焦点。任何人都可以帮我解决它。这是我的代码片段。

    Provider provider = Provider.getCurrentProvider(true);
// bind shortcut
provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), x -> {
homePage.setVisible(!homePage.isVisible());
if(homePage.isVisible()){
// TODO: 2020/10/1 request focus here
homePage.requestFocusInWindow();
homePage.requestFocus();

KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.clearGlobalFocusOwner();

log.info("hasFocus? " + homePage.hasFocus());
log.info("isActive? " + homePage.isActive());
}
});

我尝试过的:

  1. requestFocus 和 requestFocusInWindow,不起作用
  2. 我阅读了 requestFocus 的源代码。它说
     * This method cannot be used to set the focus owner to no Component at
* all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
* instead.

所以我尝试了 focusManager.clearGlobalFocusOwner() 但它仍然不起作用。

最佳答案

通常,当您想要在父容器(例如 JPanelJFrame 等)中获得焦点时,您可以通过调用 requestFocusInWindow() 方法进入其子项之一。

我建议您不要在 JFrame 中请求焦点。在其中一个组件中调用 requestFocusInWindow()

现在就用户体验而言,我会将焦点放回上一个关注的组件。为了获得 JFrame 的焦点组件,我们调用了 jframe.getFocusOwner()。但是,如果 JFrame 处于状态 MINIMIZED 或处于后台,因为它没有焦点,getFocusOwner 返回 null.

因此,为了在调用全局键监听器之前找到最后一个获得焦点的组件,您也可以为焦点事件注册一个全局 AWT 监听器:

Toolkit.getDefaultToolkit().addAWTEventListener(e -> {
if (e.getID() == FocusEvent.FOCUS_LOST) {
if (e.getSource() instanceof Component) {
lastFocusedComponent = (Component) e.getSource();
}
}
}, FocusEvent.FOCUS_EVENT_MASK);

每次焦点改变时都会触发监听器。因此,您可以安全地获得具有焦点的实际最后一个组件,消除了为 null 的机会,因为它是触发事件的组件。

在它之后你所要做的就是调用 requestFocusInWindow 到它:

provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), e -> {
frame.setVisible(!frame.isVisible());
if (frame.isVisible())
SwingUtilities.invokeLater(lastFocusedComponent::requestFocusInWindow);
});

一个有效的完整示例(您可以自己确认焦点已恢复):

public class FocusExample {
private static Component lastFocusedComponent;

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JTextField leftField = new JTextField(10);
JTextField rightField = new JTextField(10);

frame.setLayout(new FlowLayout());
frame.add(leftField);
frame.add(rightField);

Toolkit.getDefaultToolkit().addAWTEventListener(e -> {
if (e.getID() == FocusEvent.FOCUS_LOST) {
if (e.getSource() instanceof Component) {
lastFocusedComponent = (Component) e.getSource();
}
}
}, FocusEvent.FOCUS_EVENT_MASK);

Provider provider = Provider.getCurrentProvider(true);

provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), e -> {
frame.setVisible(!frame.isVisible());
if (frame.isVisible())
SwingUtilities.invokeLater(lastFocusedComponent::requestFocusInWindow);
});

frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
});

}
}

关于Java Swing如何让JFrame获得焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64158223/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com