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

Mnemonics Orientation is broken in RTL and Bidi enabled JMenu and JMenuItem

    Details

    • Subcomponent:
    • CPU:
      x86
    • OS:
      generic, windows_2000

      Description

      Name: jbT81659 Date: 09/27/2000

      OS: Win98-Arabic/Hebrew
      JDK:1.4.0-Beta32

      This bug applies to other Swing components like JButton, JCheckBox....
      For RTL Text. The Mnemonic underscore is not displayed under the correct character
      in RTL and bidi text. The Mnemonics underscore is displayed under the last
      character of the word (Farthest left) instead of the first
      character (Farthest right).

      To reproduce bug:
      1- Compile and run the following code
      2- Do "alt+g". Note that English Menu opened
      3- Note that the Mnemonics for each JMenuItem is displayed correctly under the first character
      4- Try to use the corresponding Arabic or Hebrew Mnemonics for the other JMenus
      5- Note that there is no rsponse

      --------Code-----------

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

      public class mnemonics extends JApplet
      {
          public void init()
          {
              JFrame frame = new JFrame("\u0645\u062b\u0627\u0644");
              frame.setJMenuBar(new jMenuX());
              frame.setSize(500, 400);
              frame.setVisible(true);
          }
          public static void main(String[] argv)
          {
              jMenuX example = new jMenuX();
              example.pane = new JTextPane();
              example.pane.setPreferredSize(new Dimension(250, 300));
              example.pane.setBorder(new BevelBorder(BevelBorder.LOWERED));
              JFrame frame = new JFrame("\u0645\u062b\u0627\u0644");
              frame.getContentPane().add(example, BorderLayout.NORTH);
              frame.getContentPane().add(example.pane, BorderLayout.SOUTH);
              frame.setFont(new Font("Lucida Sans Regular", Font.PLAIN,8));
              frame.setSize(500, 400);
              frame.setVisible(true);
              frame.addWindowListener( new WindowAdapter()
              {
                 public void windowClosing( WindowEvent e)
                 {
                    System.exit(0);
                 }
              });
           }
      }
      class jMenuX extends JMenuBar implements ActionListener
      {
            public JTextPane pane;

         String[] fileItemsEnglish = new String[]
         {
             "\u0041\u0042\u0043\u0044",
             "\u0061\u0062\u0063\u0064",
             "\u0065\u0066\u0067\u0068",
             "\u0030\u0031\u0032\u0033"
         };


         String[] fileItemsArabic = new String[]
         {
             "\u062c\u062f\u064a\u062f",
             "\u0641\u062a\u062d",
             "\u062d\u0641\u0638",
             "\u062e\u0631\u0648\u062c"
         };


         String[] fileItemsHebrew = new String[]
         {
             "\u05d7\u05d3\u05e9",
             "\u05e4\u05ea\u05d9\u05d7\u05d4",
             "\u05e9\u05de\u05d9\u05e8\u05d4",
             "\u05d9\u05e6\u05d9\u05d0\u05d4"
         };

         String[] fileItemsBidi = new String[]
         {
             "\u062c\u062f\u064a\u062f\u0020\u05d7\u05d3\u05e9",
             "\u0641\u062a\u062d\u0020\u05e4\u05ea\u05d9\u05d7\u05d4",
             "\u062d\u0641\u0638\u0020\u05e9\u05de\u05d9\u05e8\u05d4",
             "\u05d9\u05e6\u05d9\u05d0\u05d4\u0020\u062e\u0631\u0648\u062c"
         };

         char[] fileShortcutsEnglish = { '\u0041','\u0061','\u0065','\u0030' };
         char[] fileShortcutsArabic = { '\u062c','\u0641','\u062d','\u062e' };
         char[] fileShortcutsHebrew = { '\u05d7','\u05e4','\u05e9','\u05d9' };
         char[] fileShortcutsBidi = { '\u062c','\u0641','\u05de','\u05d9' };

         public jMenuX()
         {

            JMenu fileMenu = new JMenu("English");
            JMenu Menu2 = new JMenu("Menu2 \u0639\u0631\u0628\u064a");
            JMenu Menu3 = new JMenu("Menu3 \u05e2\u05d1\u05e8\u05d9\u05ea");
            JMenu Menu4 = new JMenu("Menu4 Bidi\u05e2\u05d1\u05e8\u05d9\u05ea\u0020\u0639\u0631\u0628\u064a");
            fileMenu.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
            Menu2.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
            Menu3.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
            Menu4.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
            fileMenu.setMnemonic('G');
            Menu2.setMnemonic('\u0639');
            Menu3.setMnemonic('\u05e2');
            Menu4.setMnemonic('\u05d1');


            for (int i=0; i < fileItemsEnglish.length; i++)
            {
                JMenuItem item = new JMenuItem(fileItemsEnglish[i]);
                item.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
                item.setMnemonic(fileShortcutsEnglish[i]);
                item.addActionListener(this);
                fileMenu.add(item);
            }

            for (int i=0; i < fileItemsArabic.length; i++)
            {
                JMenuItem item = new JMenuItem(fileItemsArabic[i]);
                item.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
                item.setMnemonic(fileShortcutsArabic[i]);
                item.addActionListener(this);
                Menu2.add(item);
            }


            for (int i=0; i < fileItemsHebrew.length; i++)
            {
                JMenuItem item = new JMenuItem(fileItemsHebrew[i]);
                item.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
                item.setMnemonic(fileShortcutsHebrew[i]);
                item.addActionListener(this);
                Menu3.add(item);
            }
            for (int i=0; i < fileItemsBidi.length; i++)
            {
                JMenuItem item = new JMenuItem(fileItemsBidi[i]);
                item.setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
                item.setMnemonic(fileShortcutsBidi[i]);
                item.addActionListener(this);
                Menu4.add(item);
            }

      this.setPreferredSize( new Dimension(400, 40));
            add(fileMenu);
            add(Menu2);
            add(Menu3);
            add(Menu4);
           }

          public void actionPerformed(ActionEvent e)
          {
              try
              {
                 setFont(new Font("Lucida Sans Regular",Font.PLAIN,14));
                 pane.getStyledDocument().insertString(0 ,"Action ["+e.getActionCommand()+"] performed!\n", null);
              }
              catch (Exception ex)
                      {;}

           }
      }


      WorkAround:
      ======================================================================

      Name: yyT116575 Date: 08/08/2001


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


      OS: Windows 2000

      the bug appears when running this code.
      JMenuBar /JMenu doesn't work correctly when arabic orientation

      How to reproduce the bug:
      when running the code:
      click on "A Menu" menu then click on the right arrow keys the focus goes to left
      instead it's acting as it is english orientation,
      right arrow key goes to the left
      left arrow key goes to the right.

      also the popup menu displayed to the right.



      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.JMenu;
      import javax.swing.JMenuItem;
      import javax.swing.JCheckBoxMenuItem;
      import javax.swing.JRadioButtonMenuItem;
      import javax.swing.ButtonGroup;
      import javax.swing.JMenuBar;
      import javax.swing.KeyStroke;
      import javax.swing.ImageIcon;

      import javax.swing.JTextArea;
      import javax.swing.JScrollPane;
      import javax.swing.JFrame;

      /*
       * This class exists solely to show you what menus look like.
       * It has no menu-related event handling.
       */
      public class test extends JFrame {
        JTextArea output;
        JScrollPane scrollPane;

        public test() {
          JMenuBar menuBar;
          JMenu menu, submenu;
          JMenuItem menuItem;
          JCheckBoxMenuItem cbMenuItem;
          JRadioButtonMenuItem rbMenuItem;

          addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
              System.exit(0);
            }
          });

          //Add regular components to the window, using the default BorderLayout.
          Container contentPane = getContentPane();
          output = new JTextArea(5, 30);
          output.setEditable(false);
          scrollPane = new JScrollPane(output);
          contentPane.add(scrollPane, BorderLayout.CENTER);
          contentPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

          //Create the menu bar.
          menuBar = new JMenuBar();
          menuBar.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          setJMenuBar(menuBar);

          //Build the first menu.
          menu = new JMenu("A Menu");
          menu.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menu.setMnemonic(KeyEvent.VK_A);
          menu.getAccessibleContext().setAccessibleDescription(
              "The only menu in this program that has menu items");
          menuBar.add(menu);

          //a group of JMenuItems
          menuItem = new JMenuItem("A text-only menu item", KeyEvent.VK_T);
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setAccelerator(KeyStroke.getKeyStroke(
              KeyEvent.VK_1, ActionEvent.ALT_MASK));
          menuItem.getAccessibleContext().setAccessibleDescription(
              "This doesn't really do anything");
          menu.add(menuItem);

          menuItem = new JMenuItem("Both text and icon",
              new ImageIcon("images/middle.gif"));
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setMnemonic(KeyEvent.VK_B);
          menu.add(menuItem);

          menuItem = new JMenuItem(new ImageIcon("images/middle.gif"));
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setMnemonic(KeyEvent.VK_D);
          menu.add(menuItem);

          //a group of radio button menu items
          menu.addSeparator();
          ButtonGroup group = new ButtonGroup();

          rbMenuItem = new JRadioButtonMenuItem("A radio button menu item");
          rbMenuItem.setSelected(true);
          rbMenuItem.setMnemonic(KeyEvent.VK_R);
          group.add(rbMenuItem);
          menu.add(rbMenuItem);

          rbMenuItem = new JRadioButtonMenuItem("Another one");
          rbMenuItem.setMnemonic(KeyEvent.VK_O);
          group.add(rbMenuItem);
          menu.add(rbMenuItem);

          //a group of check box menu items
          menu.addSeparator();
          cbMenuItem = new JCheckBoxMenuItem("A check box menu item");
          cbMenuItem.setMnemonic(KeyEvent.VK_C);
          menu.add(cbMenuItem);

          cbMenuItem = new JCheckBoxMenuItem("Another one");
          cbMenuItem.setMnemonic(KeyEvent.VK_H);
          menu.add(cbMenuItem);

          //a submenu
          menu.addSeparator();
          submenu = new JMenu("A submenu");
          submenu.setMnemonic(KeyEvent.VK_S);

          menuItem = new JMenuItem("An item in the submenu");
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setAccelerator(KeyStroke.getKeyStroke(
              KeyEvent.VK_2, ActionEvent.ALT_MASK));
          submenu.add(menuItem);

          menuItem = new JMenuItem("Another item");
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          submenu.add(menuItem);
          menu.add(submenu);

          //Build second menu in the menu bar.
          menu = new JMenu("Another Menu");
          menu.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menu.setMnemonic(KeyEvent.VK_N);
          menu.getAccessibleContext().setAccessibleDescription(
              "This menu does nothing");
          menuItem = new JMenuItem("An item in the submenu");
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setAccelerator(KeyStroke.getKeyStroke(
              KeyEvent.VK_2, ActionEvent.ALT_MASK));
          menu.add(menuItem);
              
              
          menuBar.add(menu);
              
          menu = new JMenu("Another Menu");
          menu.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menu.setMnemonic(KeyEvent.VK_N);
          menu.getAccessibleContext().setAccessibleDescription(
              "This menu does nothing");
          menuItem = new JMenuItem("An item in the submenu");
          menuItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
          menuItem.setAccelerator(KeyStroke.getKeyStroke(
              KeyEvent.VK_2, ActionEvent.ALT_MASK));
          menu.add(menuItem);
          menuBar.add(menu);
              
        }

        public static void main(String[] args) {
          test window = new test();

          window.setTitle("MenuLookDemo");
          window.setSize(450, 260);
          window.setVisible(true);
        }
      }
      (Review ID: 129596)
      ======================================================================

      Name: yyT116575 Date: 08/23/2001


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

      in RIGHT_TO_LEFT orientation the LEFT & RIGHT keys work go in the wrong visiual direction.

      in the following example when menu "two" is selected the left key should take us to menu "Three" .. instead it goes to "one".

      source:

      import javax.swing.*;

      public class MenuTest extends JFrame {
        
        public MenuTest() {
          JMenuBar bar = new JMenuBar();
          bar.setComponentOrientation(java.awt.ComponentOrientation.RIGHT_TO_LEFT);

          JMenu menu = new JMenu("One");
          menu.add(new JMenuItem("1.1"));
          menu.add(new JMenuItem("1.2"));
          bar.add(menu);
          
          menu = new JMenu("Two");
          menu.add(new JMenuItem("2.1"));
          menu.add(new JMenuItem("2.2"));
          bar.add(menu);
          
          menu = new JMenu("Three");
          menu.add(new JMenuItem("3.1"));
          menu.add(new JMenuItem("3.2"));
          bar.add(menu);
          
          setJMenuBar(bar);
          pack();
          setSize(300, 400);
          setVisible(true);
        }
        
        public static void main(String args[]) {
          new MenuTest();
        }
      }
      (Review ID: 130451)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                idk Igor Kushnirskiy (Inactive)
                Reporter:
                jbenavrasunw Jonathan Benavraham (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: