Ensiajatuksia
(jo käytännössä hylätty, kts. summary)
Tarvitaan clienttiin kirjanpito mitä nappuloita rekisteröity ??
Ei jos hyväksytään samat nappulat. Tällöin kaikki keyPressed eventit täytyy lopettaa: evt.stop(), jolloin vain yksi pääsee läpi. Vaikeuksia tietää mikä komponentti nappaa eventin ekana ja viimeisenä.
Serveripuolella törmäksen hanskausta? Kuinka?
Paras lähtökohta lienee sitoa tapahtuma containeriin (pystyy sieppaamaan tapahtuman, vaikkei haluttu komponentti olekaaan "focused")? Komponenteille ("esim. button") voi sitten tehdä yhteisen API:n jolla voi asettaa "vihjeet", jotka olisi vain tyhmiä tekstejä.
"TEOLLISUUSVAKOILUA"
QT:
button.setDefault(); // asettaa laukaistavaksi entterillä button.setAccel( Key_Esc ); // asettaa napin "pikanäppäimekssi". Huomaa termi accelerator.
Siis ilm. sidottu ihan mihin tahansa komponenttiin.
Swing:
Sama kuin QT:ssä eli suoraan komponenttiin jButton.setMnemonic(KeyEvent?.VK_1); // alt-jotain
Laajemmat mahdollisuudet: http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html
Each JComponent has one action map and three input maps. The input maps correspond to the following focus situations:
JComponent.WHEN_FOCUSED The component has the keyboard focus. The WHEN_FOCUSED input map is typically used when the component has no children. For example, buttons bind the Space key using the WHEN_FOCUSED map.
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT The component contains (or is) the component that has the focus. This input map is commonly used for a composite component — a component whose implementation depends on child components. For example, JTables make all their bindings using WHEN_ANCESTOR_OF_FOCUSED_COMPONENT so that if the user is editing, the up-arrow key (for example) still changes the selected cell.
JComponent.WHEN_IN_FOCUSED_WINDOW The component's window either has the focus or contains the component that has the focus. This input map is commonly used for mnemonics or accelerators, which need to be active regardless of where focus is in the window. When the user types a key, the JComponent key event processing code searches through one or more input maps to find a valid binding for the key. When it finds a binding, it looks up the corresponding action in the action map. If the action is enabled, the binding is valid and the action is executed. If it's disabled, the search for a valid binding continues. If more than one binding exists for the key, only the first valid one found is used. Input maps are checked in this order:
The focused component's WHEN_FOCUSED input map. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input map. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input maps of the focused component's parent, and then its parent's parent, and so on, continuing up the containment hierarchy. Note: Input maps for disabled components are skipped. The WHEN_IN_FOCUSED_WINDOW input maps of all the enabled components in the focused window are searched. Because the order of searching the components is unpredictable, avoid duplicate WHEN_IN_FOCUSED_WINDOW bindings!
Eli normaalist GUI kirjaustoissa shortcut keyn saa asettaa suoraan "napille". IMO näin meidänkin täytyy siis homma hoitaa.
SUMMARUM/STRATEGIA RFC
Selain toteutettavuuden kannalta vaadittaneen pientä yksinertaistusta tuohon Javan malliin. WHEN_IN_FOCUSED_WINDOW on hieman laaja ja WHEN_FOCUSED taso voitaneen jättää pois Java-puolelta (eli nämä helppo toteuttaa tarvittaessa teemassa). Tehdään "välimallin ratkaisu" ?
- Ohjelmoijan täytyy saada sitoa pikanäppäin komponenttiin (esim. nappi implements shortcutJotain)
- Kaikki Javasta sidotut pikanäpäpimet yllä olevaa swingtyyliä mukaillen tyyppiä WHEN_IN_FOCUSED_COMPONENT_CONTAINER_THAT_CAPTURES_SHORTCUT_KEYS
- Eventit täytyy siis JS puolella sitoa containeriin, koska focus ei välttämättä ole komponentissa, johon shortcut viittaa."Rendausvaiheessa" täytyy etsiä lähin "shortcutcontainer", johon tapahtuma sidotaan. Niitä voisi yksinkertaisuuden vuoksi olla vain Window ja Panel.
- Ei tehdä törmäysten tarkistusta, jätetään ohjelmoijan vastuulle. Ensimmäisen tapahtuman siepanneen JS kuuntelijan täytyy pysäyttää tapahtuman eteneminen ts. vain yksi shortcutkeyevent ajetaan.
- "Pikanäppäimien näytttötoiminnossa": getShortCutContainer(evt.target).showShorcuts()
