<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