<Swing Dev> A proposal for a behavior change about mnemonic key
Pavel Porvatov
pavel.porvatov at oracle.com
Wed Sep 14 15:16:56 UTC 2011
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
> <mailto: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
>> <mailto: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
>>> <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
>>>
>>
>>
>>
>>
>> --
>> 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/20110914/e37dcd36/attachment.html>
More information about the swing-dev
mailing list