JDK-8013453 : Last JMenu in JMenuBar selected instead of first
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • Submitted: 2013-04-27
  • Updated: 2023-01-13
  • Resolved: 2023-01-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
In a JMenuBar containing a first JMenu with the same Mnemonic as the last JMenu, the last JMenu is selected using the keys [Alt]+[<Mnemonic>] and not the first JMenu.
Considering this a bug, I report this to you.
The enhancement could be that the firstJMenu is selected instead of the last.


JUSTIFICATION :
It is disturbing and annoying to select a JMenu from a JMenuBar and to get a wrong one selected.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The first JMenu with a Mnemonic is selected instead of the last with the same Mnemonic.

ACTUAL -
In a JMenuBar containing a first JMenu with the same Mnemonic as the last JMenu, the last JMenu is selected using the keys [Alt]+[<Mnemonic>] and not the first JMenu.


---------- BEGIN SOURCE ----------
// File with main()
package menutest;

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextArea;


public class MenuTest extends JFrame {

/**
 * generated serialVersionUID
 */
  private static final long serialVersionUID = 5727487056953216993L;

  MenuTest mtMe;

  String hEIconFileName; // The filename for the Icon
  
  MenuItemListener mil;
  
  static String theTitle; //  " HTML Editor " ;
  
  // components and controls
  
  JMenuBar         jmb01;
    JMenu           jmMenuTest;
      JMenuItem       jmiMTNew;
    JMenu           jmSearch;
    JMenu           jmInsert;
      JMenuItem       jmiPatterns;
    JMenu           jmFont;
      JMenuItem       jmiSetFont;
    JMenu           jmHelp;
      JMenuItem       jmiHelpIntro;
    JMenu           jmRun;

  JTextArea    jta;
  
  // ==========================================================================
  // work data
  
  // ==========================================================================
  // constructors
  
public MenuTest() {
    super();

    mtMe = this;
    
    setLayout( new BorderLayout() );
    
    theTitle =  " Menu Test " ;

    jmb01 = new JMenuBar();
    setJMenuBar( jmb01 );
    
    jmMenuTest = new JMenu( theTitle );
    jmMenuTest.setMnemonic( 'M' );
    jmb01.add( jmMenuTest );
    
      jmiMTNew = new JMenuItem(  " New "  );
      jmiMTNew.setMnemonic( 'N' );
      jmMenuTest.add( jmiMTNew );
    
    jmSearch = new JMenu(  " Search "  );
    jmSearch.setMnemonic( 'S' );
    jmb01.add( jmSearch );
    
     jmInsert = new JMenu(  " Insert "  );
     jmInsert.setMnemonic( 'I' );
     jmb01.add( jmInsert );

       jmiPatterns = new JMenuItem(  " Patterns "  );
       jmiPatterns.setMnemonic( 'P' );
       jmInsert.add( jmiPatterns );

     jmFont = new JMenu(  " Font "  );
     jmFont.setMnemonic( 'F' );
     jmb01.add( jmFont );

       jmiSetFont = new JMenuItem(  " Set Font "  );
       jmiSetFont.setMnemonic( 'F' );
       jmFont.add( jmiSetFont );

    jmRun = new JMenu(  " Run "  );
    jmRun.setMnemonic( 'R' );
    jmb01.add( jmRun );

    jmHelp = new JMenu(  " My Help "  );
    jmHelp.setMnemonic( 'M' );
    jmb01.add( jmHelp );

      jmiHelpIntro = new JMenuItem(  " Intro "  );
      jmiHelpIntro.setMnemonic( 'I' );
      jmHelp.add( jmiHelpIntro );


    // connect MenuItems and event handling
    mil = new MenuItemListener( this );

    jmiMTNew.addActionListener( mil );
    jmiPatterns.addActionListener( mil );
    jmiSetFont.addActionListener( mil );
    jmiHelpIntro.addActionListener( mil );
    
    jta = new JTextArea(10, 40 );
    add( jta, BorderLayout.CENTER );

    
    setTitle( theTitle );
    
    pack();

    setSize( 400, 100 );
    setLocationRelativeTo( null );


    addWindowListener( new MTWdwListener() );

    // window closing
    setDefaultCloseOperation( EXIT_ON_CLOSE );

}
  // ==========================================================================

  // --- main() ---------------------------------------------------------------
public static void main(String[] args) {

MenuTest mt = new MenuTest();
mt.setVisible( true );

} // --- end method main() --------------------------------------------------

  // ========================================================================
  class MTWdwListener extends WindowAdapter {
    public void windowClosing( WindowEvent we ) {
      System.exit( 0 ); // dispose();
    }
  } // ======================================================================

} // === end class HTMLEditor =================================================

// second File ################################################
package menutest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class MenuItemListener implements ActionListener {

MenuTest mt;

MenuItemListener( MenuTest mt ) {
this.mt    = mt;
}

public void actionPerformed( ActionEvent ae ) {

JMenuItem jmiSrcOfae = ( JMenuItem )ae.getSource();

if ( jmiSrcOfae == mt.jmiMTNew ) {
    JOptionPane.showMessageDialog( mt,  " New not implemented "  );
return;
}

if ( jmiSrcOfae == mt.jmiPatterns ) {
    JOptionPane.showMessageDialog( mt,  " Insert Patterns not implemented "  );
return;
}

if ( jmiSrcOfae == mt.jmiSetFont ) {
    JOptionPane.showMessageDialog( mt,  " Set Font not implemented "  );
return;
}

if ( jmiSrcOfae == mt.jmiHelpIntro ) {
    JOptionPane.showMessageDialog( mt,  " Help Intor not implemented "  );
return;
}

} // --- end method actionPreformed() ---------------------------------------

} // === end class MenuItemListener ===========================================


---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Choose another Mnemonic for the two JMenu objects
Comments
Can you please specify where it works that way? I could not find any app which does that way, so asking..
13-01-2023

I agree it may not be specified but it is how it works: if there are two items which use the same mnemonic, usually the first one is activated on the first key press, and so on. I also agree it is somewhat a bad design where two menus or two menu items or even two controls / components have the same mnemonic, at the same time it's not uncommon. If this happens, the first match gets activated first — no the last one. So, I think it's a valid problem. Whether we fix it or not is another case. If we don't fix it, then the status should be Won't Fix because it is not “Not an Issue”.
12-01-2023

I dont see in spec that first menu of same mnemonic should be selected. It should be the last which would overwrite the previous mnemonic, if same and would be selected. Also, I think it's a bad UI design to have same mnemonic and native OS menus always select different char as mnemonic
11-01-2023

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

It requires to rewrite KeybordManager.fireKeyboardAction: // There is no well defined order for WHEN_IN_FOCUSED_WINDOW // bindings, but we give precedence to those bindings just // added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW // bindings are accessed before those of the JRootPane (they // both have a WHEN_IN_FOCUSED_WINDOW binding for enter). for (int counter = v.size() - 1; counter >= 0; counter--) {
27-05-2014

We've reviewed your bulk request (120 bugs) and are OK with deferring them to JDK 9. You can go ahead and update these to: - Set label to 8-defer-approved - FixVersion to 9 Thanks for doing a great job of summarizing the details for the bulk deferral for us! Kind regards, Mathias
19-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

jdk8: SQE ok to defer!
17-09-2013

This old behavior is reproducible with jdk 7 and 6.
02-09-2013

It is hard to debug because of assertion in native code.
29-05-2013