已解决11/03/13:
FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion
事实证明我使用的是Mac,我在上面找到了答案。希望这可以帮助任何其他Mac用户遇到同样的问题。
我创建了一款需要专注于JPanel的游戏,但自从我将JFrame设为全屏后,游戏面板mainPanel无法获得焦点。基本上,我看起来像这个SSCCE:
package com.StackOverflow;
import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainClass extends JFrame
{
private JPanel panel; //private MainPanel mainPanel;
public MainClass()
{
panel = new JPanel(true); // mainPanel = new MainPanel();
// I already set these attributes in my parent class of MainPanel, MyPanel
panel.setLayout(null);
panel.setOpaque(false);
panel.setFocusable(true);
panel.setVisible(true);
setUndecorated(true);
setLocation(0, 0);
add(panel); // add(mainPanel)
pack();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
gs.setFullScreenWindow(this);
System.out.format("%-30s:%10s\n", "panel is displayable", panel.isDisplayable());
System.out.format("%-30s:%10s\n", "panel is focusable", panel.isFocusable());
System.out.format("%-30s:%10s\n", "panel is visible", panel.isVisible());
System.out.format("%-30s:%10s\n", "panel can request focus", panel.requestFocusInWindow());
// mainPanel.run();
}
public static void main(String args[])
{
new MainClass();
}
}
输出:
mainPanel is displayable : true
mainPanel is focusable : true
mainPanel is visible : true
mainPanel can request focus : false
从Eclipse的Component.requestFocusInWindow()定义:
请求此Component获取输入焦点,如果此Component的顶级祖先已经是焦点窗口。此组件必须是可显示的,可聚焦的,可见的,并且其所有祖先(顶级窗口除外)必须对于要授予的请求是可见的。将尽一切努力履行要求;但是,在某些情况下,可能无法这样做。在此Component收到FOCUS_GAINED事件之前,开发人员绝不能假定此Component是焦点所有者。
具体而言,除了这一点之外,我还创建了一个MyPanel类,它扩展了JPanel并实现了AcionListener和Runnable。我使用MainPanel扩展了该类,并将MainPanel对象添加到全屏JFrame。
MainPanel是我控制和显示具有keylistener的游戏的地方。在我制作JFrame全屏之前,游戏工作得很好,但现在的问题是它无法获得焦点,即使其中的所有内容仍然在运行(敌人仍在屏幕上追逐玩家,但玩家无法响应。)
我向父类MyPanel添加了一个focuslistener,但它从未丢失或获得焦点,直到我直接使用mainPanel.requestFocus(),但输出告诉我它获得了焦点然后立即丢失它。我甚至在JFrame上尝试过setFocusable(false)。
当我在JFrame上使用setVisible(true),然后revalidate()时,输出发生了变化,我被告知mainPanel.requestFocusInWindow()更改为true。然后输出告诉我mainPanel获得焦点,失去焦点,然后再次获得焦点。然而,整个时间,我的mac只是在每按一次键时发出哔哔声。有时,requestFocusInWindow()返回false,但它仍然说mainPanel获得,丢失,然后最终获得焦点。
在requestFocusInWindow()的文档的第二部分中,它说:
此方法返回布尔值。如果返回false,则保证请求失败。 如果返回true,则除非被否决,否则请求将成功,或者在本机窗口系统授予请求之前发生特殊事件(如处置组件的对等方)。同样,返回值为true表示请求可能成功,开发人员必须永远不要假设此Component是焦点所有者,直到此Component收到FOCUS_GAINED事件。
那部分是我的头脑,所以即使你无法解决这个问题,如果你知道这意味着什么,那可能会让我走上正轨。
如果我找到解决方案,我会在此发布更新。