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

JMenu steals focus from JInternalFrame and never restores it

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Cannot Reproduce
    • Affects Version/s: 1.3.0
    • Fix Version/s: None
    • Component/s: client-libs

      Description



      Name: skT45625 Date: 05/09/2000


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


      In 1.3 the code for BasicMenuItemUI was changed to
      add an additional check that breaks restoring focus to components
      residing in internal frames. Specifically, in the ChangeHandler inner
      class there is method called validateKeyboardActions which is called
      before a JMenu is posted and after it is unposted. The code keeps track
      of which component had the focus before the menu is posted and will
      attempt to restore the focus to that component after the menu is
      unposted.

      Here's the problem. In 1.3 a check was added that ignores components
      that don't share the same rootpane as the menu being posted. If the
      application is set up so the menubar is parented by a toplevel JFrame
      and the internal frames are parented by a JDesktopPane(which resides in
      the JFrame's contentPane), then this check will always fail! Here's the
      offending code fragment from the validateKeyboardActions method:

         if ((wasFocused instanceof JComponent) &&
            ((JComponent)wasFocused).getRootPane() != menu.getRootPane()) {
            wasFocused = null;
         }

      The "wasFocused" variable contains the component that had the focus
      before the JMenu was posted.


      Here's a testcase that clearly shows the bug. Just access the "Test" menu and
      you'll see that the focus is not restored to the component in the internal
      frame that had it before the menu got posted.

      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;

      public class foo extends JFrame {

         public static void main(String[] args) {
            new foo();
         }
         public foo() {
            addWindowListener(new WindowAdapter() {
               public void windowClosing(WindowEvent e) {
                  System.exit(0);
               }}
            );

            JDesktopPane dtp = new JDesktopPane();
            setContentPane(dtp);

            final JInternalFrame jif = new JInternalFrame("Test",true,true,true,true);
            jif.setOpaque(true);
            jif.setBackground(Color.gray);
            jif.getContentPane().setLayout(new FlowLayout());
            jif.setBounds(0,50,600,200);
            jif.setVisible(true);
            dtp.add(jif);

            // HACK ALERT - use timer to get initial frame selected
            Timer t = new Timer(1000, new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  try {
                     jif.setSelected(true);
                  } catch (Exception x) {}
               }
            });
            t.setRepeats(false);
            t.start();

            JButton b = new JButton("JButton");
            JTextField tf = new JTextField(10);
            jif.getContentPane().add(b);
            jif.getContentPane().add(tf);
            jif.pack();
            FocusHandler fh = new FocusHandler();
            b.addFocusListener(fh);
            tf.addFocusListener(fh);

            JMenuBar mb = new JMenuBar();
            setJMenuBar(mb);
            JMenu menu = new JMenu("Test");
            JMenuItem mi = new JMenuItem("Dummy Item");
            menu.add(mi);
            mb.add(menu);

            pack();
            setBounds(300,300,400,200);
            setVisible(true);
         }

         private class FocusHandler implements FocusListener {
            public void focusLost(FocusEvent e) {
               System.out.println("FOCUS LOST, SRC="+e.getSource().getClass().getName
      ());
            }
            public void focusGained(FocusEvent e) {
               System.out.println("FOCUS GAINED, SRC="+e.getSource().getClass
      ().getName());
            }
         }
      }
      (Review ID: 104620)
      ======================================================================

        Attachments

          Activity

            People

            • Assignee:
              apikalev Andrey Pikalev
              Reporter:
              skondamasunw Suresh Kondamareddy (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: