如何使 JFrame 获得焦点?

11

我正在编写一个小游戏,其中包含一个 JFrame 用于主游戏,另一个 JFrame 用于显示分数。问题是,当我完成构建它们时,得分的 JFrame 总是处于焦点状态!我尝试过调用 scoreDisplay.toFront()、scoreDisplay.requestFocus(),甚至:

display.setState(JFrame.ICONIZED);
display.setState(JFrame.NORMAL);

有没有办法使这个工作起来?谢谢, 约翰·穆拉诺


对于未来想要将JFrame聚焦的访问者,请查看我在页面下方的答案,其中使用了frame.requestFocus()。被接受的答案解决了OP的问题,但解决方案非常特定于他的情况。 - Erick Robertson
7个回答

14

调用requestFocus()方法。

这并不保证一定会成功,因为有很多原因会导致操作系统不允许一个框架获得焦点。可能有另一个应用程序中优先级更高的框架。还有一些Linux桌面环境(如果我没记错的话)不允许框架请求焦点。

为了增加成功的机会,我还建议在请求焦点之前调用toFront()方法。

frame.setVisible(true);
frame.toFront();
frame.requestFocus();
请记住,这些都不是保证,因为框架处理,特别是焦点和层叠,都与操作系统有关。所以将框架设置为可见,将其移至前面,并请求焦点。一旦放弃EDT,操作系统可能会将焦点放在框架上。最起码,窗口应该在最上面。

11

切换 alwaysOnTop

参见此处:

http://forums.sun.com/thread.jspa?threadID=5124278

在API中阅读toFront的说明 http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Window.html#toFront

某些平台可能不允许该VM将其窗口置于本地应用程序或其他VM的窗口上方。

例如,在Windows操作系统上,toFront会导致任务栏上的图标闪烁,但窗口仍然停留在后面。

唯一可以强制窗口前置的是setAlwaysOnTop。

frame.setAlwaysOnTop(true); 
frame.setAlwaysOnTop(false);

谢谢。这对我有用,但需要注意的是,在frame.setVisible(true)之后必须立即调用它们。我想这很有道理,但我一直在分开做。 - ensignr

4

2
我尝试过了,这种方法不起作用。无论如何还是谢谢! - John Murano

4
你有没有考虑将得分设置在与游戏框架相同的框架中?
另一个可能的(快速且简单的)选择是按相反的顺序创建它们,或者至少(如果得分取决于游戏)以相反的顺序显示它们。
score.setVisible( true );
game.setVisible( true );

我猜想目前它们是:

game.setVisible( true );
score.setVisible( true );

4
这个解决方案解决了发帖者的问题,但并没有回答标题中的问题。 - Erick Robertson

1

只需在JOptionPaneMessageDialog代码上方添加以下代码行...this.setAlwaysOnTop(false);


0

toFront() 在我遇到类似情况的时候对我很有用,我想让一个JFrame创建另一个JFrame,但第一个JFrame仍然保持焦点。新的JFrame总是获取焦点。

requestFocus() 不起作用。
requestFocusInWindow() 不起作用。
无论是从JFrame还是GlassPane或getContentPane()或JPanel()中调用上述两种方法之一,都不起作用。
setAlwaysOnTop(true) 不起作用。

在JFrame子类中:

   public void configure () {
      if (glassPane == null) {
         return;
      }
      final boolean vis = ! glassPane.isVisible (); // Toggle
      glassPane.setVisible (vis);
      if (vis) {
         configFrame = new ConfigFrame ("Configuration", props, glassPane, this);
         configFrame.addWindowListener (new AdapterForClosingSubs (configureToggle));
         toFront ();
      } else {
         configFrame.setVisible (false);
         configFrame.dispose ();
         configFrame = null;
      }
      if (getFocusOwner () != null) {
         System.out.println ("configure focus owner " + getFocusOwner ().getName ());
      }
   }


   private final Runnable configureToggle = () -> {
      configure ();
   };

顺便说一下,Java 17。


-1
frame.setExtendedState( JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);

请尝试上述方法...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接