Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6741366

JInternalFrame.restoreSubcomponentFocus() steals focus from other windows

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.6.0_10-rc"
      Java(TM) SE Runtime Environment (build 1.6.0_10-rc-b28)
      Java HotSpot(TM) Server VM (build 11.0-b15, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux aristeas 2.6.24-19-generic #1 SMP Fri Jul 11 23:41:49 UTC 2008 i686 GNU/Linux


      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Running the compiz window manager with the default window focus settings.

      A DESCRIPTION OF THE PROBLEM :
      If a new JInternalFrame is opened and is set as the selected JInternalFrame (calling JInternalFrame.setSelected(true)) while another window is selected, the owning window of the JDesktopPane steals the focus from the current window.

      This is probably because restoreSubcomponentFocus() in JInternalFrame uses requestFocus() rather than requestFocusInWindow().

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Start up a JDesktopPane in a JFrame.
      Move focus to another widow.
      Have the program select a JInternalFrame in the JDesktopPane.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      You would expect that global focus would remain on the currently focused window. The new JInternalFrame would show up in the (unfocused) Java window. When the Java window gains focus, the new JInternalFrame would be the focused component within that window.
      ACTUAL -
      Instead, focus shifts from my currently selected window to the Java window (specifically to the new JInternalFrame).

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;

      public class InternalFrameTest {

        public static void main(String[] argv) {
          JFrame jf = new JFrame();
          JDesktopPane jdp = new JDesktopPane();
          jdp.setSize(200,200);
          jf.setSize(200,200);
          jf.add(jdp);
          jf.setVisible(true);

          JInternalFrame jif = new JInternalFrame();
          jif.setSize(100,100);
          jif.setVisible(true);

          jdp.add(jif);

          try {
            // this is where you select another window
            Thread.currentThread().sleep(10000);
          } catch (Exception e) {

          }
          try {
            System.out.println("selecting jif");
            jif.setSelected(true);
          } catch (Exception e) {

          }

        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I can override all of my JInternalFrames with this:

        public void restoreSubcomponentFocus() {
          Component lLastFocusOwner = getMostRecentFocusOwner();
          if (lLastFocusOwner == null) {
            lLastFocusOwner = getContentPane();
          }
          lLastFocusOwner.requestFocusInWindow();
        }

      But it's a bit painful and really shouldn't be necessary.

      I can also tell my window manager to be extra strict on allowing windows to steal focus, but that prevents plenty of valid instances when a window should take keyboard focus on its own.

            psadhukhan Prasanta Sadhukhan
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: