Mac:JPanel:requestFocusInWindow()返回false,但isDisplayable(),isFocusable()和isVisible()不适用于全屏JFrame

时间:2013-11-03 06:09:55

标签: java macos focus jframe fullscreen

已解决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事件。

那部分是我的头脑,所以即使你无法解决这个问题,如果你知道这意味着什么,那可能会让我走上正轨。

如果我找到解决方案,我会在此发布更新。

0 个答案:

没有答案