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