获得对 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 的关注的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有单击事件的情况下使特定的 TabItem 获得对 TabControl 的关注?
Java / Swing:从JPanel内部获取Window / JFrame