获得对 JPanel 的关注

Posted

技术标签:

【中文标题】获得对 JPanel 的关注【英文标题】:Obtaining focus on a JPanel 【发布时间】:2011-01-09 06:20:45 【问题描述】:

我在JFrame 中有一个JPanel。我已经注册了一个KeyListener,基于它我想更新JPanel。我遇到的问题是我无法将注意力集中在JPanel 上,因此我的KeyListener 将无法工作。我已经知道KeyListener 可以正常工作,因为我使用JFrame 注册了它并且它运行良好。我的代码现在是这样的:

myFrame.setFocusable(false);
myPanel.setFocusable(true);
myPanel.addKeyListener(myKL);
myFrame.add(myPanel);

以前有人遇到过这样的问题吗?在这方面我有什么遗漏吗?

P.S.:我在 JPanel 中没有任何组件,我只是在背景上绘制了一个图像,所以我需要将焦点放在 JPanel 本身而不是它里面的东西上。

【问题讨论】:

嗯,添加 myPanel.requestFocus() 这对我有用。你运行的是什么版本的 Java? 也许发布一个 SSCCE(简单的自包含可编译示例)来重现这一点。这会给其他人一些工作和帮助。我还通过将问题缩小到最小范围来注意到问题,有时我可以自己找到解决方案。 【参考方案1】:

试试这样的:

    myFrame.addFocusListener(new FocusAdapter() 

        /**
         * @inheritDoc
         */
        @Override
        public void focusGained(FocusEvent aE) 
            myPanel.requestFocusInWindow();
        
    );

【讨论】:

【参考方案2】:

使用setFocusable(true),然后使用requestFocusInWindow()。但后者必须在包含面板的窗口可见之后完成,您可能需要为此注册一个窗口侦听器并在窗口中执行requestFocusInWindow()激活的处理程序代码。

注意:特别是在窗口可见之后,而不仅仅是在调用setVisible(true)之后。

【讨论】:

那么我的代码如何告诉何时窗口可见,如果等到setVisible(true)被调用之后不够? 对我来说,当我在frame.pack() 之后调用panel.requestFocusInWindow() 时,它起作用了。 一般情况下,将 Swing 命令包装到 SwingUtilities.invokeLater(()->...); 中,即使您已经在 Swing 线程上,也可以解决此类问题,因为(文档说)“这将在所有未决的 AWT 事件发生后发生已处理。”例如:如果你想保护 Swing 事件代码不引起它自己的执行,你可以在开头设置一个布尔值,最后你重置布尔值,但后者必须在一个 invokeLater() 中,否则重置在事件序列中为时过早。【参考方案3】:

试试

panel.setFocusable(true);
panel.setRequestFocusEnabled(true);

// some code here

panel.grabFocus();

【讨论】:

【参考方案4】:

我有时会遇到类似的问题。我注意到在某些情况下,最好将焦点放在框架内的面板中的特定控件上(例如,您希望键盘输入进入的输入框),而不是请求焦点窗格本身。

【讨论】:

【参考方案5】:

尽管您指出面板可以聚焦,但面板并没有要求获得焦点。尝试使用myPanel.requestFocus();

【讨论】:

感谢您的回答。尝试了 requestFocus() 和 requestFocusInWindow(),它们都没有使面板获得焦点。您还有其他建议吗? 这可能取决于您何时调用它。例如,不要在 JPanel 的构造函数中调用它,因为它会在面板显示之前被调用。 谢谢大卫,这个答案对我有用,我不知道我无法从构造函数进行调用。一旦我将 requestFocus() 移动到在屏幕上显示后被调用的方法,它就可以完美地工作。

以上是关于获得对 JPanel 的关注的主要内容,如果未能解决你的问题,请参考以下文章

Swing下,鼠标点击组件不是自动获得焦点的么?

如何在没有单击事件的情况下使特定的 TabItem 获得对 TabControl 的关注?

请问使用C#怎么得到微信公众号获得关注者openid

Java / Swing:从JPanel内部获取Window / JFrame

关于JPanel函数的关注点:paintcomponent()

我可以在 JEditorPane 上方但在 JTabbedPane 下方获得 JTextField 吗?