Domanda

Esiste un modo per ottenere una scorciatoia da tastiera a livello di sistema (globale) eseguire un'azione in un'applicazione Java?

Eventuali attacchi AWT / Swing?

È stato utile?

Soluzione

Non c'è, ma in Windows puoi usare questo:

jintellitype

Sfortunatamente non c'è nulla di cui io sia a conoscenza per Linux e OSX, probabilmente è per questo che non viene fornito con Java pronto all'uso.

Se lo trovi per le altre piattaforme pubblicalo qui per favore :)

Solo per curiosità, cosa ci fai?

Altri suggerimenti

Sono l'autore di JIntellitype e posso dirti per certo che questo deve essere fatto in modo nativo in DLL e chiamato da Java JNI proprio come fa JIntellitype. Questo è un hook a livello di sistema operativo che non è implementato in JDK, quindi è necessario utilizzare librerie come JIntellitype e jxGrabKey. Per quanto ne so nessuno ne ha ancora scritto uno per OSX.

JIntellitype è open source su Github, quindi se vuoi avere un'idea di come funziona, consulta source codice

Ho appena trovato https://github.com/kwhat/jnativehook

Sembra essere multipiattaforma.

Ecco il loro codice di esempio per ascoltare la pressione dei tasti:

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

public class GlobalKeyListenerExample implements NativeKeyListener {
    public void nativeKeyPressed(NativeKeyEvent e) {
        System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));

        if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
            GlobalScreen.unregisterNativeHook();
        }
    }

    public void nativeKeyReleased(NativeKeyEvent e) {
        System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    public void nativeKeyTyped(NativeKeyEvent e) {
        System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
    }

    public static void main(String[] args) {
        try {
            GlobalScreen.registerNativeHook();
        }
        catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }

        GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
    }
}

Il controllo dei modificatori si basa su maschere di bit (cose che tutti dovremmo sapere ma dimentichiamo sempre :-P):

    boolean isAltPressed = (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0;
    boolean isShiftPressed = (e.getModifiers() & NativeKeyEvent.SHIFT_MASK) != 0;

Questo è possibile combinarlo con KeyCode:

if (e.getKeyCode() == NativeKeyEvent.VK_2 && isShiftPressed && isAltPressed){...}

Questo esempio è stato modificato da qui

Dovresti anche modificare il comportamento di registrazione predefinito altrimenti spammerà la console:

// Get the logger for "org.jnativehook" and set the level to warning.
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);

// Don't forget to disable the parent handlers.
logger.setUseParentHandlers(false);

L'esempio di codice è tratto da qui

AGGIORNAMENTO: Non so se è possibile agganciare eventi dall'esterno della JVM. Penso che un componente Swing / AWT debba focalizzarsi affinché questo funzioni.

Ti consigliamo di collegarti alla coda degli eventi AWT Java per essere assolutamente sicuro di poter ottenere un keypress globale (jvm wide).

Usa

EventQueue ev = Toolkit.getSystemEventQueue();
// MyCustomEventQueue extends EventQueue and processes keyboard events in the dispatch
ev.push(new MyCustomEventQueue());

class MyEventQueue extends EventQueue
{
    protected void dispatchEvent(AWTEvent event)
    {
       // all AWTEvents can be indentified by type, KeyEvent, MouseEvent, etc
       // look for KeyEvents and match against you hotkeys / callbacks
    }
}

Penso che potrebbero esserci altri modi per realizzare pressioni di tasti globali con le mappe d'azione. In realtà ho usato la metra sopra

Per Windows è necessario un hook di tastiera dll. Puoi inizializzare la tua DLL da Java, che causerà la registrazione del listener. Otterrai ciò di cui hai bisogno. Controlla msdn per hook dll o hook di tastiera. Uno di questi dovrebbe crearti.

Per Linux penso che dovrebbe essere più facile, ma non l'ho mai fatto da solo.

http://ubuntuforums.org/showthread.php?t=864566

Il primo risultato di Google per " linux ascolta le pressioni di tasti globali " (senza virgolette) si presenta qualcosa che penso possa aiutarti per gli ambienti X11

OSX potrebbe essere in grado di utilizzare una soluzione simile a questa. Ma alla fine, probabilmente avrai bisogno di una dll per ogni piattaforma, a meno che JNA non possa farlo senza problemi, quindi il peggio è fatto.

JDIC (Java Desktop Integration) potrebbe aiutare
https://jdic.dev.java.net/

Sembra essere un po 'non mantenuto per me. Non ne sono sicuro.
Se qualcuno ne sa di più, per favore segnala!
Sono anche molto interessato a questa funzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top