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

Sean Chou zhouyx at linux.vnet.ibm.com
Tue Sep 20 07:56:05 UTC 2011


Hi Pavel,

    I just tested linux gtk platform.  With gtk2+, ubuntu linux with kernel
2.6.38, xfce, x86_32.
I set four menus with mnemonic "i". Press "alt+i" will travel through four
menus. The difference
is that each menu must be closed with "esc" before "alt+i" opens the next
one.

    So press "alt+i" opens "File", and press "esc" to close it;
    then press "alt+i" opens "Edit", and press "esc" to close it;
    ... for next menu with mnemonic "i"

I attached the test application and its ui file. If it is blocked, please
use
this link:
https://docs.google.com/leaf?id=0B8kRxsymP7imOGU1NjhiM2ItMGQ5Ni00NWNhLWJmMDQtZjZiZmQzN2U4ZGUw&hl=en_US

Ubuntu x86_32 should work.


So, I think both windows and linux gtk have supported traversal of same
mnemonic keyed
items already.


2011/9/14 Pavel Porvatov <pavel.porvatov at oracle.com>

> **
> 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>
>
>  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>
>
>  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>
>
>  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> wrote:
>
>  Hi,
>
>     Is there anybody interested in this feature? Or any other comments?
>
> 2011/4/21 Sean Chou <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>
>
> 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
>
>
>


-- 
Best Regards,
Sean Chou
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110920/2ac4b053/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gtk_mnemonicTest.tar
Type: application/x-tar
Size: 40960 bytes
Desc: not available
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20110920/2ac4b053/gtk_mnemonicTest.tar>


More information about the swing-dev mailing list