package org.hwo.ui; import java.awt.KeyboardFocusManager; import java.awt.Window; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JInternalFrame; import javax.swing.SwingUtilities; /* * Copies the fix for bug 6505027 from Java 7 * http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/f727cac13697 * Some support code (private) needed to be copied as well */ public class InternalFrameFix extends JInternalFrame { public InternalFrameFix() { addPropertyChangeListenerIfNecessary(); } private java.awt.Component lastFocusOwner; private void setLastFocusOwner(java.awt.Component lastFocusOwner) { this.lastFocusOwner = lastFocusOwner; } private static boolean initializedFocusPropertyChangeListener = false; private static void addPropertyChangeListenerIfNecessary() { if (!initializedFocusPropertyChangeListener) { PropertyChangeListener focusListener = new FocusPropertyChangeListener(); initializedFocusPropertyChangeListener = true; KeyboardFocusManager.getCurrentKeyboardFocusManager(). addPropertyChangeListener(focusListener); } } private static class FocusPropertyChangeListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().equals("permanentFocusOwner")) { updateLastFocusOwner((java.awt.Component) e.getNewValue()); } } } private static void updateLastFocusOwner(java.awt.Component component) { if (component != null) { java.awt.Component parent = component; while (parent != null && !(parent instanceof Window)) { if (parent instanceof InternalFrameFix) { // Update lastFocusOwner for parent. ((InternalFrameFix) parent).setLastFocusOwner(component); } parent = parent.getParent(); } } } @Override public void restoreSubcomponentFocus() { if (isIcon()) { super.restoreSubcomponentFocus(); //delegated to super implementation, because it's correct there } else { java.awt.Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); if ((component == null) || !SwingUtilities.isDescendingFrom(component, this)) { // FocusPropertyChangeListener will eventually update // lastFocusOwner. As focus requests are asynchronous // lastFocusOwner may be accessed before it has been correctly // updated. To avoid any problems, lastFocusOwner is immediately // set, assuming the request will succeed. setLastFocusOwner(getMostRecentFocusOwner()); if (lastFocusOwner == null) { // Make sure focus is restored somewhere, so that // we don't leave a focused component in another frame while // this frame is selected. setLastFocusOwner(getContentPane()); } if (!lastFocusOwner.hasFocus()) { lastFocusOwner.requestFocus(); } } } } }