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
