<Swing Dev> A proposal for a behavior change about mnemonic key

Pavel Porvatov pavel.porvatov at oracle.com
Wed Sep 14 15:16:56 UTC 2011


Hi Sean,
> Hi Pavel,
>
>     Let's see if this time works. The attachement just contains the 
> exe file written by C#, the application is very simple, I just drag a 
> menu to the default WinForm in VS2003.
>     Please change the extension from exe1 to exe after unzip as gmail 
> doesn't allow exe file to be sent.
Yes, I see. And what about other platforms/lafs? Your patch affects 
behavior of all lafs. So we must be sure, that such behavior is correct 
for every supported platform...

Regards, Pavel
>
> 2011/9/13 Pavel Porvatov <pavel.porvatov at oracle.com 
> <mailto:pavel.porvatov at oracle.com>>
>
>     Hi Sean,
>
>     I think the attached sample was removed because I didn't get any
>     attachments...
>
>     Regards, Pavel
>
>>     Hi Pavel,
>>
>>        I found C# Form application treats Mnemonics in menu in this
>>     way. I attached the sample
>>     application. Press alt+i will iterate over three menu.
>>
>>     2011/9/13 Pavel Porvatov <pavel.porvatov at oracle.com
>>     <mailto:pavel.porvatov at oracle.com>>
>>
>>         Hi Sean,
>>>         Hi,
>>>
>>>            Thanks.
>>>
>>>            So is there any one can give me a suggestion about what
>>>         shall I
>>>         do if we want these feature ?  Thanks again.
>>         First of all you should file a bug (RFE actually). BTW:
>>         before reviewing the fix I'd like to ask about OS behavior
>>         when there are several components with the same mnemonic. How
>>         Windows XP/Vista/7 and Linux (Gnome/KDE) manage the described
>>         situation?
>>
>>         Regards, Pavel
>>
>>
>>>
>>>         2011/7/6 Jean-Remi Desjardins <jeanremi.desjardins at gmail.com
>>>         <mailto:jeanremi.desjardins at gmail.com>>
>>>
>>>             I think that sounds like a great idea!
>>>
>>>             Regards,
>>>             Jean-Rémi Desjardins
>>>
>>>             Sent from my iPhone (so don't expect me to be too verbose)
>>>
>>>             On 2011-07-06, at 5:42 AM, Sean Chou
>>>             <zhouyx at linux.vnet.ibm.com
>>>             <mailto:zhouyx at linux.vnet.ibm.com>> wrote:
>>>
>>>>             Hi,
>>>>
>>>>                Is there anybody interested in this feature? Or any
>>>>             other comments?
>>>>
>>>>             2011/4/21 Sean Chou <zhouyx at linux.vnet.ibm.com
>>>>             <mailto:zhouyx at linux.vnet.ibm.com>>
>>>>
>>>>                 Hi,
>>>>
>>>>                    I have a simple patch to demo the new behavior.
>>>>                 With the patch, the focus will go through the
>>>>                 radiobuttons with mnemonic key Y when alt+y is
>>>>                 pressed instead of select the last.
>>>>
>>>>
>>>>                 The patch is as follows:
>>>>
>>>>                 diff -r 554adcfb615e src/share/classes/javax/swing/KeyboardManager.java
>>>>                 --- a/src/share/classes/javax/swing/KeyboardManager.java	Wed Mar 16 15:01:07 2011 -0700
>>>>                 +++ b/src/share/classes/javax/swing/KeyboardManager.java	Thu Mar 17 14:57:14 2011 +0800
>>>>                 @@ -251,6 +251,93 @@
>>>>                                    }
>>>>                                } else if ( tmp instanceof Vector) { //more than one comp registered for this
>>>>                                    Vector v = (Vector)tmp;
>>>>                 +
>>>>                 +                 /* The below code is added to make sure the focus is not always
>>>>                 +                    transferred to the last component in the vector when
>>>>                 +                    more than one component have the same mnemonic
>>>>                 +                 */
>>>>                 +	              if ((e.getModifiers()&  Event.ALT_MASK) == Event.ALT_MASK) {
>>>>                 +                      /* Mnemonic key should transfer the focus only, do not select.
>>>>                 +                       * The following code works in this way:
>>>>                 +                       * 1. If only one component in the vector is visible, fireBinding on it.
>>>>                 +                       * 2. If multi-components in the vector are visible, move the focus to next component.
>>>>                 +                       *    2.1 If the next component is not a JAbstractButton, fireBinding on it.
>>>>                 +                       *    2.2 If the next component is a JMenu, which is a JAbstractButton, fireBinding
>>>>                 +                       *        on it to open the menu.
>>>>                 +                       *    2.3 If the next component is another JAbstractButton like JRadioButton. Request
>>>>                 +                       *        focus on it instead of fireBinding. To AVOID SELECTION&  CLICK of the button.
>>>>                 +                       * 3. If the code is triggered by release event, fireBinding on current focus component
>>>>                 +                       *    instead of move focus.
>>>>                 +                       * 4. Further consideration: there may be more swing control like JMenu, or customized
>>>>                 +                       *    controls, which may break this behavior.
>>>>                 +                       */
>>>>                 +                      // This has alt as it's modifier so this could be a mnemonic
>>>>                 +                      Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
>>>>                 +                      {
>>>>                 +                      // If only one visible component, invoke it.
>>>>                 +                      int visibleComponentCounter = 0;
>>>>                 +                      int nextFocus = 0;
>>>>                 +                      for (int i =  0; i<  v.size(); i++){
>>>>                 +                          JComponent c = (JComponent) v.elementAt(i);
>>>>                 +                          if (c.isShowing()&&  c.isEnabled()){
>>>>                 +                    	         visibleComponentCounter++ ;
>>>>                 +                    		      nextFocus = i;
>>>>                 +                    	     }
>>>>                 +                      }
>>>>                 +                      if (visibleComponentCounter == 1){
>>>>                 +                    	     JComponent tmpc = (JComponent) v.elementAt(nextFocus);
>>>>                 +                    	     fireBinding(tmpc, ks, e, pressed);
>>>>                 +                          if (e.isConsumed())
>>>>                 +                        	  return true;
>>>>                 +                      }
>>>>                 +                      // If multi-components are visible, do not select the button, just move the focus.
>>>>                 +                      for (int counter = v.size() - 1; counter>= 0; counter--) {
>>>>                 +                          JComponent c = (JComponent) v.elementAt(counter);
>>>>                 +                          if (c.isShowing()&&  c.isEnabled()) {
>>>>                 +                              if ((c == focusOwner)
>>>>                 +                                       || (c instanceof JLabel&&  ((JLabel) c).getLabelFor() == focusOwner)) {
>>>>                 +                                  if (e.getID() == KeyEvent.KEY_RELEASED){
>>>>                 +                                	     nextFocus = counter;
>>>>                 +                                	     break;
>>>>                 +                                  }
>>>>                 +                            	    nextFocus = (counter - 1 + v.size()) % v.size();
>>>>                 +                                  break;
>>>>                 +                              }
>>>>                 +                          }
>>>>                 +                      }
>>>>                 +                      for (; nextFocus>= 0; nextFocus--) {
>>>>                 +                          JComponent c = (JComponent) v.elementAt(nextFocus);
>>>>                 +                          if (c.isShowing()&&  c.isEnabled()) {
>>>>                 +                              break;
>>>>                 +                          }
>>>>                 +                      }
>>>>                 +                      if (nextFocus>= 0) {
>>>>                 +                          JComponent tmpc = (JComponent) v.elementAt(nextFocus);
>>>>                 +                          // Next is the hack for this accessibility:
>>>>                 +                          // For general Buttons, do not press them, but request focus only.
>>>>                 +                          // For special buttons like JMenu, needs press.
>>>>                 +                          // If it is not a button, let the component handles by itself.
>>>>                 +                          if (!(tmpc instanceof javax.swing.AbstractButton)){
>>>>                 +                        	   fireBinding(tmpc, ks, e, pressed);
>>>>                 +                              if (e.isConsumed())
>>>>                 +                            	    return true;
>>>>                 +                          }
>>>>                 +                          if (tmpc instanceof JMenu ) {
>>>>                 +                              fireBinding(tmpc, ks, e, pressed);
>>>>                 +                              tmpc.requestFocusInWindow();
>>>>                 +                              if (e.isConsumed())
>>>>                 +                                  return true;
>>>>                 +                          } else {
>>>>                 +                              boolean result = tmpc.requestFocusInWindow();
>>>>                 +                              e.consume();
>>>>                 +                              return result;
>>>>                 +                          }
>>>>                 +                      }
>>>>                 +                      // If it is not handled here, default behavior is selecting the last.
>>>>                 +                      }
>>>>                 +                 }
>>>>                 +
>>>>                 +
>>>>                                    // 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
>>>>
>>>>
>>>>
>>>>
>>>>                 2011/4/1 Sean Chou <zhouyx at linux.vnet.ibm.com
>>>>                 <mailto:zhouyx at linux.vnet.ibm.com>>
>>>>
>>>>                     Hi all,
>>>>
>>>>                        In daily use, we may encounter a problem of
>>>>                     mnemonic key: there may be several
>>>>                     controls want the same key to be set as
>>>>                     mnemonic key. It is not common but it does exist.
>>>>
>>>>                        Current openjdk implementation allows users
>>>>                     to set a same mnemonic key for
>>>>                     different controls; but during the execution,
>>>>                     when the mnemonic key is pressed,
>>>>                     the last control always gets the action. Users
>>>>                     are not able to touch other controls with
>>>>                     that mnemonic key. This may confuse them.
>>>>
>>>>                        If all the controls with the same mnemonic
>>>>                     key can be accessed through, for
>>>>                     example, when the mnemonic key is pressed, the
>>>>                     focus is moved to the last control,
>>>>                     and when the mnemonic key is pressed again, the
>>>>                     focus is moved to the second control
>>>>                     with that mnemonic, it will give user the
>>>>                     choice to select other controls.
>>>>
>>>>                        Here is an example for the case:
>>>>
>>>>                     package test;
>>>>
>>>>                     import java.awt.BorderLayout;
>>>>                     import java.awt.Container;
>>>>                     import javax.swing.ButtonGroup;
>>>>                     import javax.swing.JFrame;
>>>>                     import javax.swing.JRadioButton;
>>>>
>>>>                     public class TestFocus extends JFrame {
>>>>                     public TestFocus() {
>>>>                     Container pane = getContentPane();
>>>>                     pane.setLayout(new BorderLayout());
>>>>                     JRadioButton btn1,btn2,btn3;
>>>>                     btn1 = new JRadioButton("Yes");
>>>>                     btn1.setMnemonic('Y');
>>>>                     btn2 = new JRadioButton("Yup");
>>>>                     btn2.setMnemonic('Y');
>>>>                     btn3 = new JRadioButton("No");
>>>>                     btn3.setMnemonic('N');
>>>>                     btn3.setSelected(true);
>>>>                     ButtonGroup group = new ButtonGroup();
>>>>                     group.add(btn1);
>>>>                     group.add(btn2);
>>>>                     group.add(btn3);
>>>>                     pane.add(btn1,BorderLayout.NORTH);
>>>>                     pane.add(btn2,BorderLayout.CENTER);
>>>>                     pane.add(btn3,BorderLayout.SOUTH);
>>>>                     setSize(200,200);
>>>>                     setVisible(true);
>>>>                     setDefaultCloseOperation(EXIT_ON_CLOSE);
>>>>                     }
>>>>                     public static void main(String[] args) {
>>>>                     new TestFocus();
>>>>                     }
>>>>                     }
>>>>
>>>>
>>>>
>>>>
>>>>                     -- 
>>>>                     Best Regards,
>>>>                     Sean Chou
>>>>
>>>>
>>>>
>>>>
>>>>                 -- 
>>>>                 Best Regards,
>>>>                 Sean Chou
>>>>
>>>>
>>>>
>>>>
>>>>             -- 
>>>>             Best Regards,
>>>>             Sean Chou
>>>>
>>>
>>>
>>>
>>>         -- 
>>>         Best Regards,
>>>         Sean Chou
>>>
>>
>>
>>
>>
>>     -- 
>>     Best Regards,
>>     Sean Chou
>>
>
>
>
>
> -- 
> Best Regards,
> Sean Chou
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110914/e37dcd36/attachment.html>


More information about the swing-dev mailing list