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

MNEMONIC CONFLICTS IN DISABLED/HIDDEN MENU ITEMS

XMLWordPrintable

    • beta2
    • x86
    • windows_xp



      Name: rv122619 Date: 03/15/2004

      Compile and run the following program:

      import java.awt.Dimension;
      import java.awt.GridBagConstraints;
      import java.awt.GridBagLayout;
      import java.awt.Insets;
      import java.awt.Point;
      import java.awt.event.ActionEvent;
      import java.awt.event.WindowEvent;

      import javax.swing.AbstractAction;
      import javax.swing.JButton;
      import javax.swing.JDialog;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JMenu;
      import javax.swing.JMenuBar;
      import javax.swing.JMenuItem;
      import javax.swing.JOptionPane;
      import javax.swing.JPanel;
      import javax.swing.JTextField;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;

      /*
       *
       *
       *
       *
       */
      public class MainFrame extends JFrame
      {
         private AbstractAction m_actFile;
         private AbstractAction m_actExit;
         private AbstractAction m_actSave;
         private AbstractAction m_actSaveAs;
         private AbstractAction m_actPrint;
         private AbstractAction m_actProperties;
         private AbstractAction m_actNew;
         private AbstractAction m_actZoo;

         public MainFrame()
         {
            setDefaultCloseOperation( EXIT_ON_CLOSE );
            initialize();
            setLocation( new Point( 200, 200 ) );
            setSize( new Dimension( 550, 250 ) );
         }

         private void initialize()
         {
            setTitle( "MenuTest" );

            createActions();
            createMainMenu();
            createContents();
         }
         
         private void createActions()
         {
            m_actFile = new cFileAction();
            m_actExit = new cExitAction();
            m_actPrint = new cPrintAction();
            m_actProperties = new cPropertiesAction();
            m_actNew = new cNewAction();
            m_actZoo = new cZooAction();
            m_actSave = new cSaveAction();
            m_actSaveAs = new cSaveAsAction();
            
            m_actSave.setEnabled( false );
         }
         
         private void createMainMenu()
         {
            JMenuBar menuMain = new JMenuBar();

            JMenuItem miZoo = new JMenuItem( m_actZoo );
            JMenuItem miPrint = new JMenuItem( m_actPrint );
            miZoo .setVisible( false );
            miPrint.setVisible( false );
                  
            JMenu menuFile = new JMenu( m_actFile );
            menuFile.add( m_actNew );
            menuFile.add( miZoo );
            menuFile.add( m_actSave );
            menuFile.add( m_actSaveAs );
            menuFile.add( miPrint );
            menuFile.add( m_actProperties );
            
            menuFile.add( m_actExit );
            
            menuMain.add( menuFile );
            
            this.setJMenuBar( menuMain );
         }

         private void createContents()
         {
         }
         
         public static void main( String[] saArgs )
         {
            // set the UI to the system UI
            try
            {
               UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
            }
            catch (ClassNotFoundException e) {}
            catch (IllegalAccessException e) {}
            catch (InstantiationException e) {}
            catch (UnsupportedLookAndFeelException e) {}

            // create the main frame and show it
            MainFrame f = new MainFrame();
            f.setVisible( true );
         }

            
         protected class cFileAction extends AbstractAction
         {
            public cFileAction()
            {
               putValue( AbstractAction.NAME, "File" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Files" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'F' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
            }
         } // cFileAction
         
         protected class cExitAction extends AbstractAction
         {
            public cExitAction()
            {
               putValue( AbstractAction.NAME, "Exit" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Exits" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'x' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               // there should be a better way to do this but there is no close
               // and this seems to be what the system exit menu does, so ...
               MainFrame.this.dispatchEvent( new WindowEvent( MainFrame.this, WindowEvent.WINDOW_CLOSING ) );
            }
         } // cExitAction
         
         protected class cNewAction extends AbstractAction
         {
            public cNewAction()
            {
               putValue( AbstractAction.NAME, "New" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "News" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'n' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "New" );
            }
         } // cNewAction
         
         protected class cZooAction extends AbstractAction
         {
            public cZooAction()
            {
               putValue( AbstractAction.NAME, "Zoo" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Zoo" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'z' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "Zoo" );
            }
         } // cZooAction
         
         protected class cSaveAction extends AbstractAction
         {
            public cSaveAction()
            {
               putValue( AbstractAction.NAME, "Save" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Saves" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 's' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "Save" );
            }
         } // cSaveAction
         
         protected class cSaveAsAction extends AbstractAction
         {
            public cSaveAsAction()
            {
               putValue( AbstractAction.NAME, "Save as" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Saves as" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 's' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "Save as" );
            }
         } // cSaveAsAction
         
         protected class cPrintAction extends AbstractAction
         {
            public cPrintAction()
            {
               putValue( AbstractAction.NAME, "Print" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Prints" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'p' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "Print" );
            }
         } // cPrintAction
         
         protected class cPropertiesAction extends AbstractAction
         {
            public cPropertiesAction()
            {
               putValue( AbstractAction.NAME, "Properties" );
               putValue( AbstractAction.SHORT_DESCRIPTION, "Properties" );
               putValue( AbstractAction.MNEMONIC_KEY, new Integer( 'p' ) );
               putValue( AbstractAction.SMALL_ICON, null );
            }
            
            public void actionPerformed( ActionEvent e )
            {
               JOptionPane.showMessageDialog( MainFrame.this, "Properties" );
            }
         } // cPrropertiesAction
         
      }

      Press Alt-F to drop the File menu. New is selected. However, when Alt-P, Alt-S or Alt-X is selected, there is no response.

      Under 1.4.1 we noted that the above program exercised odd behaviour:

      Press S and nothing appears to be selected. Actually, Save is selected. It shouldn't be because it is disabled. Press S again and Save as is selected. You can keep pressing S. That case doesn't concern me as much as the others but it is an unexpected behavior.

      Press P. Print is selected but it's not visible. Press P and Properties is selected. Again you can toggle between these. This one is a real problem. It doesn't matter whether the hidden Print is enabled or not. In no case should Print ever be selected.

      Press Z. The Zoo action is activated. This should never happen because the user has no idea (because the Zoo menu item is hidden) that Z would even do anything. This one is a real problem.

      Some of this behaviour appears to be rectified under 1.5.0_b32c, but now no Alt keys seem to work.

      We would like to see the algorithm work such that one receives a list of all enabled and visible menu items for a given mnemonic. If hte list's length is one, activate that menu item. If the list is greater than 1, select the "next" menu item in the list where "next" is some algorithm that will loop through the possible candidates.


      ======================================================================

            kizune Alexander Zuev
            rverabel Raghu Verabelli (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: