acquisire keypress globali in Java
Domanda
Quindi voglio innescare un evento (mettere in pausa / non mettere in pausa alcuni contenuti multimediali) ogni volta che l'utente preme la barra spaziatrice in qualsiasi punto della mia app Swing.
Dato che ci sono così tanti controlli e pannelli che potrebbero essere focalizzati, non è davvero possibile aggiungere eventi chiave a tutti (per non parlare del grossolano).
Quindi ho trovato
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher()
che è fantastico, è possibile registrare pre-gestori di tasti globali. Tuttavia, c'è un grosso problema: gli spazi verranno digitati continuamente in campi di input, celle di tabella, ecc. E ovviamente non voglio attivare l'evento di pausa allora!
Quindi qualche idea? Forse c'è modo di rilevare globalmente se il cursore è focalizzato su qualcosa che consente l'inserimento di testo, senza dover controllare attraverso un elenco di tutti i controlli modificabili (vomito!)?
Soluzione
Penso che tu abbia risposto tu stesso - sì, penso che tu possa scoprire l'elemento corrente che ha il focus, e se è un'istanza di una certa classe di campo, ignori lo spazio ai fini dell'evento pause. Se sembra pesante, non ti preoccupare, instanceof è MOLTO veloce per la JVM (e in ogni caso stai parlando di eventi a misura d'uomo che sono un eon per un processore).
Altri suggerimenti
Sono arrugginito sul mio Swing, ma penso che dovresti provare a registrare un ascoltatore globale usando Toolkit.addAWTEventListener con un KEY_EVENT_MASK
. È quindi possibile filtrare l'elaborazione di AWTEvent in base al tipo e alla fonte.
Ok ... Beh, sto cercando di filtrare in base alla fonte. Il problema è il mio ComboBox modificabile ... Sono instanceof
javax.swing.plaf.basic.BasicComboBoxEditor$BorderlessTextField
E poiché BorderlessTextField è una classe interna privata, a quanto pare non posso fare un'istanza di controllo contro di essa.
idee?
EDIT: ok quindi funziona ....
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {
public boolean postProcessKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
Object s = e.getComponent();
if (!(s instanceof JTextField) &&
!(s instanceof JTable && ((JTable) s).isEditing())
) {
music_player.pauseEvent();
}
//System.out.println(s.getClass().toString());
}
return true;
}
});
È totalmente disgustoso e lo odio. Vorrei poter trovare un modo per verificare se il tasto premuto è stato consumato da qualsiasi componente - quindi potrei eseguire l'evento di pausa solo quando il tasto premuto non veniva azionato da alcun componente.