简体   繁体   English

FullScreen Swing组件无法在Mac OS X Mountain Lion上的Java 7上接收键盘输入

[英]FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion

Update 12/21: 更新12/21:

7u10 was recently released. 7u10最近发布。 Confirmed that: 确认:

  1. The issue still persists 这个问题仍然存在
  2. Thankfully, the workaround still functions! 值得庆幸的是,解决方法仍然有效!

Update 11/7: 更新11/7:

And we have a workaround! 我们有一个解决方法!

Leonid Romanov from Oracle on the openjdk.java.net mailing list provided some insight as to what's going on : 来自Oracle的Leonid Romanov在openjdk.java.net邮件列表中提供了一些有关正在发生的事情的见解

Well, although I'm not 100% sure yet, but it looks like when we enter full screen some other window becomes the first responder, hence the beep. 好吧,虽然我还不是100%肯定,但看起来当我们进入全屏时,其他一些窗口成为第一响应者,因此发出哔哔声。 Could you please try the following workaround: after calling setFullScreenWindow() on a frame, call setVisible(false) followed by setVisible(true). 您可以尝试以下解决方法:在框架上调用setFullScreenWindow()之后,调用setVisible(false),然后调用setVisible(true)。 This, in theory, should restore the correct first responder. 理论上,这应该恢复正确的第一响应者。

The snippet of code that seems to work is simply: 似乎有用的代码片段很简单:

dev.setFullScreenWindow(f);
f.setVisible(false);
f.setVisible(true);

I have updated the sample code with the ability to toggle this fix on and off; 我更新了示例代码,能够打开和关闭此修复程序; it is required every time a window enters fullscreen. 每次窗口进入全屏时都需要它。

In the larger context of my more complex application, I am still running into keyboard focus issues on subcomponents within the fullscreen window, where a mouse click causes my window to lose focus. 在我更复杂的应用程序的更大的上下文中,我仍然在全屏窗口中的子组件上遇到键盘焦点问题,鼠标单击导致我的窗口失去焦点。 (I'm guessing it's going to the undesired first responder window referenced above.) I'll report back when I have more information about this case - I cannot reproduce it in the smaller sample yet. (我猜它会转到上面提到的不受欢迎的第一响应者窗口。)当我有关于这种情况的更多信息时,我会报告回来 - 我还不能在较小的样本中重现它。


Update 10/31: 更新10/31:

Major update to the sample code: 示例代码的主要更新:

  • Includes toggle between FullScreen exclusive and Lion-style FullScreen modes 包括在FullScreen独占模式和Lion风格的全屏模式之间切换
  • Listens to the KeyboardFocusManager to display the hierarchy for the currently focused component 侦听KeyboardFocusManager以显示当前焦点组件的层次结构
  • Uses both input maps and KeyListener s to try to capture input 使用输入映射和KeyListener来尝试捕获输入

Also did some more digging with coworkers to try to isolate issues: 还与同事一起进行了更多挖掘,试图找出问题所在:

On one front, we tried overriding some methods in RT.jar to see if there were problems with the way the screen device is being selected. 在一方面,我们尝试覆盖RT.jar中的一些方法,以查看屏幕设备的选择方式是否存在问题。 Also tried were the entry points to the Toolkit.beep() functionality to see if the alert sounds were coming from the Java side - appears not. 还尝试了Toolkit.beep()功能的入口点,以查看警报声是否来自Java端 - 似乎没有。

On another front, it was clear that not even the native side is receiving keyboard events. 另一方面,很明显甚至本机方都没有接收键盘事件。 A coworker attributes this to a switch from an AWTView to a NSWindow in 7u6. 同事将此归因于7月6日从AWTViewNSWindow的转换。

A selection of existing Oracle bugs has been found, which you can look up here : 已找到一系列现有的Oracle错误,您可以在此处查找:


Update 10/26: 更新10/26:

Thanks to the comment by @maslovalex below regarding an Applet working on 7u5, I went back and painstakingly examined compatibility with the JDK versions for OSX: 感谢@maslovalex下面关于工作于7u5的Applet的评论,我回过头来仔细研究了与OSX的JDK版本的兼容性:

  • 10.7.1 with 7u4: Fullscreen Works! 10.7.1 with 7u4:Fullscreen Works!
  • 10.7.1 with 7u5: Fullscreen Works! 10.7.1与7u5:全屏工作!
  • 10.7.5 with 7u5: Fullscreen Works! 10.7.5与7u5:全屏工作!
  • 10.7.5 with 7u6: Fullscreen Breaks :( 10.7.5与7u6:全屏休息:(

Combined with the other tests noted elsewhere, it's clear there was an issue introduced with 7u6 that remains in 7u7 and 7u9, and it affects both Lion 10.7 and Mountain Lion 10.8. 结合其他地方提到的其他测试,很明显7u6引入的问题仍然存在于7u7和7u9,它影响了Lion 10.7和Mountain Lion 10.8。

7u6 was a major milestone release, bringing full support of the JRE and JDK to Mac OS X and also including Java FX as part of the distribution. 7u6是一个重要的里程碑版本,它将JRE和JDK全面支持到Mac OS X,并将Java FX作为发行版的一部分。 Further info is available in the Release Notes and the Roadmap . 有关详细信息,请参阅发行说明路线图 It's not tremendously surprising that such an issue could crop up as support shifts to Java FX. 这种问题可能会随着支持转向Java FX而出现并不令人惊讶。

The question becomes: 问题变成:

  1. Will Oracle fix this in a near-term release of the JDK? Oracle会在JDK的近期发布中修复此问题吗? (If you have links to existing bugs, please include them here.) (如果您有现有错误的链接,请在此处添加。)
  2. Is a workaround possible in the interim? 过渡期是否可行?

Other updates from today: 今天的其他更新:

  • I incorporated the Apple extensions approach to fullscreen mode as an alternate path of exploration (updated sample code pending cleanup). 我将Apple扩展方法整合到全屏模式中作为替代探索路径(更新的示例代码等待清理)。 The good news: input works! 好消息:输入有效! The bad news: there really don't seem to be any kiosking/isolation options. 坏消息:似乎没有任何自助/隔离选项。
    I tried killing the Dock - directly or with an App - as I understand the Dock is responsible for Command-Tab app switching, Mission Control, and Launch Pad, only to find out that it's responsible for the handling of fullscreen apps as well! 我试图直接或使用应用程序杀死Dock - 据我所知,Dock负责Command-Tab应用程序切换,Mission Control和Launch Pad,但却发现它还负责处理全屏应用程序! As such, the Java calls become non-functional and never return. 因此,Java调用变得不起作用,永远不会返回。
    If there's a way to disable Command-Tab (and Mission Control and Launchpad and Spaces) without affecting the Dock's fullscreen handling, that would be extremely useful. 如果有一种方法可以在不影响Dock的全屏处理的情况下禁用Command-Tab (以及Mission Control和Launchpad和Spaces),那将非常有用。 Alternatively, one can try to remap certain keys such as Command, but that will affect the ability to use that modifier elsewhere in the program and the system itself (not exactly ideal, when you need to Command-C to copy some text). 或者,可以尝试重新映射某些键,例如Command,但这会影响在程序中的其他位置和系统本身使用该修饰符的能力(当您需要Command-C复制某些文本时,这并不完全理想)。

  • I've had no luck with KeyListeners (I'm not receiving any callbacks), but I have a few more options to try. 我没有运气KeyListeners(我没有收到任何回调),但我还有一些选择。

  • Based on a coworker's suggestion, I tried ((sun.lwawt.macosx.LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive() via reflection. 根据同事的建议,我尝试((sun.lwawt.macosx.LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()通过反射。 The idea was that it: 这个想法是:它:
    is a native method with the comment "Returns true if the application (one of its windows) owns keyboard focus.". 是一个带有注释的本机方法“如果应用程序(其中一个窗口)拥有键盘焦点,则返回true。” Calls to this method were added in CPlatformWindow.java in the past few months related to focus logic. 在过去几个月中,在聚焦逻辑方面,CPlatformWindow.java中添加了对此方法的调用。 If it returns false in your test code, it's probably part of the problem. 如果它在您的测试代码中返回false,则可能是问题的一部分。
    Unfortunately, everywhere I checked it, the method returned true. 不幸的是,无论我在哪里检查它,该方法都返回true。 So even according to the low level system, my windows should have keyboard focus. 因此,即使根据低级系统,我的窗户应该有键盘焦点。

  • My previous optimism regarding the JAlbum fix has been dashed. 我以前对JAlbum修复的乐观态度已经破灭。 The developer posted a response on their forum that explains how they simply removed proper fullscreen support on OS X while running Java 7. They have a bug into Oracle (and I'm hoping to get the bug number). 开发人员在他们的论坛上发布了一个回复 ,解释了他们在运行Java 7时如何在OS X上删除正确的全屏支持。他们在Oracle中有一个错误(我希望得到错误号)。


Update 10/25: 更新10/25:

I have now also tried Java 7u9 on Lion 10.7.4 and have seen the exact same issue, so it's JDK- not OS-specific. 我现在也在Lion 10.7.4上尝试过Java 7u9并且看到了完全相同的问题,所以它是JDK-而不是特定于操作系统的。

The core question has become whether you can embed in a fullscreen window core Swing Components that have default handling for keyboard input ( JTextField/JTextArea or even editable combo boxes) and expect them to behave normally (without having to resort to rebuilding their basic key bindings manually). 核心问题是你是否可以嵌入一个全屏窗口核心Swing组件,它具有键盘输入的默认处理( JTextField/JTextArea或甚至可编辑的组合框)并期望它们正常运行(无需求助于重建它们的基本键绑定手动地)。 Also in question is whether other stalwarts of windowed layouts, such as using tab for focus traversal, should work. 还有一个问题是窗口布局的其他坚持者,例如使用tab进行焦点遍历,是否应该有效。

The ideal goal would be to have the ability take a windowed Swing app with all of its buttons, tabs, fields, etc. and run it in fullscreen exclusive/kiosk mode with most functionality intact. 理想的目标是让能够使用带有所有按钮,选项卡,字段等的窗口Swing应用程序,并以全屏独占/自助服务终端模式运行,大多数功能完好无损。 (Previously, I have seen that Dialog pop ups or ComboBox drop downs do not function in fullscreen on Java 6 on OS X, but other Components behave fine.) (以前,我已经看到在OS X上的Java 6上,Dialog弹出窗口或ComboBox下拉列表无法在全屏模式下运行,但其他组件表现良好。)

I'll be looking into the eawt FullScreen capabilities, which will be interesting if they support kiosk lock down options, such as eliminating Command-Tab application switching. 我将研究eawt的FullScreen功能,如果它们支持自助服务终端锁定选项,例如消除Command-Tab应用程序切换,那将会很有趣。


Original Question: 原始问题:

I have a Swing app that for years has supported FullScreen (exclusive) mode on Mac OS X up through Java 6. I've been doing compatibility testing with the latest Mountain Lion release (10.8.2 Supplemental) and Oracle's JDK 7 and noticed a glaring issue while in that mode: mouse movement and clicks work fine, but keyboard input is not delivered to the components. 我有一个Swing应用程序,多年来一直支持Mac OS X上的FullScreen(独家)模式到Java 6.我一直在使用最新的Mountain Lion版本(10.8.2补充版)和Oracle的JDK 7进行兼容性测试,并注意到了在该模式下明显的问题:鼠标移动和点击工作正常,但键盘输入未传递给组件。

(I've narrowed this down in a test case below to not being able to type into a simple JTextField while in fullscreen mode.) (我在下面的测试用例中缩小了这个范围,以便在全屏模式下无法输入简单的JTextField。)

One symptom is that each key press results in a system beep, as if the OS is disallowing keyboard events from being delivered to the application. 一个症状是每次按键都会导致系统发出蜂鸣声,就好像操作系统不允许将键盘事件传递给应用程序一样。

Separately, my application has an exit hook installed, and the Command-Q combo will trigger that hook - it's clear that the OS is listening to standard key combos. 另外,我的应用程序安装了一个退出钩子,Command-Q组合将触发该钩子 - 很明显操作系统正在监听标准的组合键。

I have tested this separately on three different Macs with various installs: 我已经在三种不同的Mac上分别测试了它,并进行了各种安装:

  • On Apple Java 6u35 and 6u37: both windowed and fullscreen modes receive input. 在Apple Java 6u35和6u37上:窗口模式和全屏模式都接收输入。
  • On Oracle Java 7u7 and 7u9: windowed mode works as expected while fullscreen has the symptoms above. 在Oracle Java 7u7和7u9上:窗口模式按预期工作,而全屏具有上述症状。

This may have been previously reported: Java Graphics Full Screen Mode not Registering Keyboard Input . 这可能是之前报道的: Java图形全屏模式未注册键盘输入 However, that question is not specific about the Java version or platform. 但是,该问题并不是关于Java版本或平台的具体问题。

Additional searching has turned up a separate fullscreen option introduced in Lion: Fullscreen feature for Java Apps on OSX Lion . 其他搜索已经在Lion中引入了一个单独的全屏选项: OSX Lion上的Java应用程序的全屏功能 I have yet to try using this approach, as keyboard input seems integral to the target use cases of FullScreen Exclusive mode, such as games. 我还没有尝试使用这种方法,因为键盘输入似乎是FullScreen Exclusive模式的目标用例不可或缺的部分,例如游戏。

There is some mention in the JavaDoc for this mode that input methods might be disabled. 在JavaDoc中有一些提及此模式的输入方法可能被禁用。 I tried to call the suggested Component.enableInputMethods(false) , but it seemed to have no effect . 我试图调用建议的Component.enableInputMethods(false) ,但似乎没有效果

I'm somewhat optimistic that there's a solution to this issue based on an entry in the release notes of a Java app I came across (JAlbum). 基于我遇到的Java应用程序(JAlbum)的发行说明中的​​条目,我对这个问题有一个解决方案,我有点乐观。 A stated fix for 10.10.6 : "Keyboard support wasn't working when running the full screen slide show on Mac and Java 7" 针对10.10.6声明修复 :“在Mac和Java 7上运行全屏幻灯片时,键盘支持无法正常工作”

My test case is below. 我的测试用例如下。 It is lightly modified from the second example in this issue (which, unmodified, also exhibits my problem): How to handle events from keyboard and mouse in full screen exclusive mode in java? 它是从这个问题的第二个例子中轻微修改的(未经修改,也表现出我的问题): 如何在java中以全屏独占模式处理键盘和鼠标的事件? In particular, it adds a button to toggle fullscreen. 特别是,它添加了一个按钮来切换全屏。

import java.lang.reflect.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;

/** @see https://stackoverflow.com/questions/13064607/ */
public class FullScreenTest extends JPanel {
    private GraphicsDevice dev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    private JFrame f = new JFrame("FullScreenTest");

    private static final String EXIT = "Exit";
    private Action exit = new AbstractAction(EXIT) {
        @Override
        public void actionPerformed(ActionEvent e) {
            Object o = dev.getFullScreenWindow();
            if(o != null) {
                dev.setFullScreenWindow(null);
            }
            f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
        }
    };
    private JButton exitBTN = new JButton(exit);

    private JTextField jtf = new JTextField("Uneditable in FullScreen with Java7u6+ on Mac OS X 10.7.3+");

    private JLabel keystrokeLabel = new JLabel("(Last Modifier+Key Pressed in JTextField)");

    private JLabel jtfFocusLabel = new JLabel("(JTextField Focus State)");

    private JLabel focusLabel = new JLabel("(Focused Component Hierarchy)");

    private JCheckBox useOSXFullScreenCB = new JCheckBox("Use Lion-Style FullScreen Mode");

    private JCheckBox useWorkaroundCB = new JCheckBox("Use Visibility Workaround to Restore 1st Responder Window");

    private static final String TOGGLE = "Toggle FullScreen (Command-T or Enter)"; 
    private Action toggle = new AbstractAction(TOGGLE) {
        @Override
        public void actionPerformed(ActionEvent e) {
            Object o = dev.getFullScreenWindow();
            if(o == null) {
                f.pack();

                /** 
                 * !! Neither of these calls seem to have any later effect.  
                 * One exception: I have a report of a 
                 * Mini going into an unrecoverable black screen without setVisible(true);  
                 * May be only a Java 6 compatibility issue.  !!
                 */
                //f.setVisible(true);
                //f.setVisible(false);

                if(!useOSXFullScreenCB.isSelected()) {
                    // No keyboard input after this call unless workaround is used
                    dev.setFullScreenWindow(f);

                    /**
                     * Workaround provided by Leonid Romanov at Oracle.
                     */
                    if(useWorkaroundCB.isSelected()) {
                        f.setVisible(false);
                        f.setVisible(true);
                        //Not necessary to invoke later...
                        /*SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                f.setVisible(false);
                                f.setVisible(true);
                            }
                        });*/
                    }
                }
                else {
                    toggleOSXFullscreen(f);
                }
            }
            else {
                dev.setFullScreenWindow(null);
                f.pack();
                f.setVisible(true);
            }

            isAppActive();
        }
    };
    private JButton toggleBTN = new JButton(toggle);

    public FullScreenTest() {            
        // -- Layout --
        this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

        exitBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        exitBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        this.add(exitBTN);

        jtf.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        jtf.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
        this.add(jtf);

        keystrokeLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        keystrokeLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        keystrokeLabel.setHorizontalAlignment(SwingConstants.CENTER);
        keystrokeLabel.setForeground(Color.DARK_GRAY);
        this.add(keystrokeLabel);

        jtfFocusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        jtfFocusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        jtfFocusLabel.setHorizontalAlignment(SwingConstants.CENTER);
        jtfFocusLabel.setForeground(Color.DARK_GRAY);
        this.add(jtfFocusLabel);

        focusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        focusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        focusLabel.setHorizontalAlignment(SwingConstants.CENTER);
        focusLabel.setForeground(Color.DARK_GRAY);
        this.add(focusLabel);

        useOSXFullScreenCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        useOSXFullScreenCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        useOSXFullScreenCB.setHorizontalAlignment(SwingConstants.CENTER);
        this.add(useOSXFullScreenCB);

        useWorkaroundCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        useWorkaroundCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        useWorkaroundCB.setHorizontalAlignment(SwingConstants.CENTER);
        this.add(useWorkaroundCB);

        toggleBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        toggleBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
        this.add(toggleBTN);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setResizable(false);
        f.setUndecorated(true);
        f.add(this);
        f.pack();

        enableOSXFullscreen(f);

        // -- Listeners --

        // Default BTN set to see how input maps respond in fullscreen
        f.getRootPane().setDefaultButton(toggleBTN);

        // Explicit input map test with Command-T toggle action from anywhere in the window
        this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), 
                toggle.getValue(Action.NAME));
        this.getActionMap().put(toggle.getValue(Action.NAME), toggle);

        // KeyListener test
        jtf.addKeyListener(new KeyAdapter() {                                                                                                                                                                                                                                                    
            public void keyPressed(KeyEvent e) {                                                                                                                                                                                                                                                  
                String ktext = "KeyPressed: "+e.getKeyModifiersText(e.getModifiers()) + "_"+ e.getKeyText(e.getKeyCode());
                keystrokeLabel.setText(ktext);
                System.out.println(ktext);
            }
        });

        // FocusListener test
        jtf.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent fe) {
                focused(fe);
            }
            public void focusLost(FocusEvent fe) {
                focused(fe);
            }
            private void focused(FocusEvent fe) {
                boolean allGood = jtf.hasFocus() && jtf.isEditable() && jtf.isEnabled();
                jtfFocusLabel.setText("JTextField has focus (and is enabled/editable): " + allGood);
                isAppActive();
            }
        });

        // Keyboard Focus Manager
        KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        focusManager.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent e) {
                if (!("focusOwner".equals(e.getPropertyName()))) return;
                Component comp = (Component)e.getNewValue();
                if(comp == null) {
                    focusLabel.setText("(No Component Focused)");
                    return;
                }
                String label = comp.getClass().getName();
                while(true) {
                    comp = comp.getParent();
                    if(comp == null) break;
                    label = comp.getClass().getSimpleName() + " -> " + label;
                }
                focusLabel.setText("Focus Hierarchy: " + label);
                isAppActive();
            }
        });
    }

    /**
     * Hint that this Window can enter fullscreen.  Only need to call this once per Window.
     * @param window
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static void enableOSXFullscreen(Window window) {
        try {
            Class util = Class.forName("com.apple.eawt.FullScreenUtilities");
            Class params[] = new Class[]{Window.class, Boolean.TYPE};
            Method method = util.getMethod("setWindowCanFullScreen", params);
            method.invoke(util, window, true);
        } catch (ClassNotFoundException e1) {
        } catch (Exception e) {
            System.out.println("Failed to enable Mac Fullscreen: "+e);
        }
    }

    /**
     * Toggle OSX fullscreen Window state. Must call enableOSXFullscreen first.
     * Reflection version of: com.apple.eawt.Application.getApplication().requestToggleFullScreen(f);
     * @param window
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static void toggleOSXFullscreen(Window window) {
        try {
            Class appClass = Class.forName("com.apple.eawt.Application");

            Method method = appClass.getMethod("getApplication");
            Object appInstance = method.invoke(appClass);

            Class params[] = new Class[]{Window.class};
            method = appClass.getMethod("requestToggleFullScreen", params);
            method.invoke(appInstance, window);
        } catch (ClassNotFoundException e1) {
        } catch (Exception e) {
            System.out.println("Failed to toggle Mac Fullscreen: "+e);
        }
    }

    /**
     * Quick check of the low-level window focus state based on Apple's Javadoc:
     *  "Returns true if the application (one of its windows) owns keyboard focus."
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static void isAppActive() {
        try {
            Class util = Class.forName("sun.lwawt.macosx.LWCToolkit");
            Method method = util.getMethod("isApplicationActive");
            Object obj = method.invoke(Toolkit.getDefaultToolkit());
            System.out.println("AppActive: "+obj);
        } catch (ClassNotFoundException e1) {
        } catch (Exception e) {
            System.out.println("Failed to check App: "+e);
        }
    }

    public static void main(String[] args) {
        System.out.println("Java Version: " + System.getProperty("java.version"));
        System.out.println("OS Version: " + System.getProperty("os.version"));

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                FullScreenTest fst = new FullScreenTest();
                if(!fst.dev.isFullScreenSupported()) {
                    System.out.println("FullScreen not supported on this graphics device.  Exiting.");
                    System.exit(0);
                }
                fst.toggle.actionPerformed(null);
            }
        });
    }
}

This is because the component to which you added the other has now lost focus, you can fix this by either: 这是因为您添加了另一个的组件现在已经失去焦点,您可以通过以下方式解决此问题:

  • calling requestFocus() on the component instance to which you add KeyBinding s 在您添加KeyBinding的组件实例上调用requestFocus()

or 要么

  • alternatively use JComponent.WHEN_IN_FOCUSED_WINDOW with KeyBinding s: 或者使用JComponent.WHEN_IN_FOCUSED_WINDOWKeyBinding

     component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "doSomething"); component.getActionMap().put("doSomething", anAction); 

Reference: 参考:

Instead, use key bindings , as shown in this FullScreenTest . 而是使用键绑定 ,如此FullScreenTest所示。 Also, consider a DocumentListener , shown here , for text components. 此外,考虑DocumentListener所示, 在这里 ,对于文本组件。

I think I finally found a solution, registering click listeners against to the JFrame itself. 我想我终于找到了一个解决方案,将点击监听器注册到JFrame本身。 (This is a class which extends JFrame, hence all the "this" references.) (这是一个扩展JFrame的类,因此所有“this”引用。)

/**
 * Toggles full screen mode. Requires a lot of references to the JFrame.
 */
public void setFullScreen(boolean fullScreen){
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice dev = env.getDefaultScreenDevice();//Gets the main screen
    if(!fullScreen){//Checks if a full screen application isn't open
        this.dispose();//Restarts the JFrame
        this.setVisible(false);
        this.setResizable(true);//Re-enables resize-ability.
        this.setUndecorated(false);//Adds title bar back
        this.setVisible(true);//Shows restarted JFrame
        this.removeMouseListener(macWorkAround);
        this.pack();
        this.setExtendedState(this.getExtendedState()|JFrame.MAXIMIZED_BOTH);//Returns to maximized state
        this.fullScreen = false;
    }
    else{
        this.dispose();//Restarts the JFrame
        this.setResizable(false);//Disables resizing else causes bugs
        this.setUndecorated(true);//removes title bar
        this.setVisible(true);//Makes it visible again
        this.revalidate();
        this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
        try{
            dev.setFullScreenWindow(this);//Makes it full screen
            if(System.getProperty("os.name").indexOf("Mac OS X") >= 0){
                this.setVisible(false);
                this.setVisible(true);
                this.addMouseListener(macWorkAround);
            }
            this.repaint();
            this.revalidate();
        }
        catch(Exception e){
            dev.setFullScreenWindow(null);//Fall back behavior
        }
        this.requestFocus();
        this.fullScreen = true;
    }
}

private MouseAdapter macWorkAround = new MouseAdapter(){
    public void mouseClicked(MouseEvent e){
        MainGUI.this.setVisible(false);
        MainGUI.this.setVisible(true);
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM