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

Pavel Porvatov pavel.porvatov at oracle.com
Mon Sep 12 16:01:13 UTC 2011


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
>

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


More information about the swing-dev mailing list