2017-05-24 3 views
1

Dies ist eine Clojure Frage bezüglich Java Swing, so dass Leute aus beiden Lagern mir vielleicht helfen können.Wie deaktiviert man die Tastatursteuerung eines JSpinner über die Pfeiltasten?

Ich arbeite an einem hydrologischen Datenvisualisierungsprogramm für meinen Job, und ich habe die größte Zeit damit verbracht, diesen herauszufinden.

Meine Anwendung basiert auf der Anzeige grafischer Niederschlagsinformationen. Die typische Nutzung umfasst Aufgaben wie die Anzeige von Niederschlagsdaten über 24 Stunden im Südosten der USA, wobei der interne Zustand des Programms die Endzeit und die Anzahl der Stunden überwacht, über die Regen angesammelt werden kann.

Die Hauptbenutzeroberfläche besteht aus einem Hauptzeichnungsfenster, ein paar Spinner und einer Statusleiste (siehe unten). Die Spinner und ihre Etiketten werden in ihrem eigenen JPanel enthalten, aber die JTextField und JPanel mit dem Ziehscheiben sind auf oberster Ebene im contentPane

View of main interface

Die keybindings in einem Format definiert sind, wie unten zu sehen:

"control S" {:type :function 
      :config :configure-shapefiles} 
"control Z" {:type :function 
      :config :configure-zooms} 
"NUMPAD0" {:type :function 
      :config :toggle-grids-on} 
"VK_DOWN" {:type :function 
      :config :prev-day} 
"VK_UP" {:type :function 
     :config :next-day} 
"VK_RIGHT" {:type :function 
      :config :next-hour} 
"VK_LEFT" {:type :function 
      :config :prev-hour}} 

Diese Konfigurationskarte in keybindings für den Inhaltsbereich des JFrame wie folgt transformiert:

(defn- set-keystroke-shortcuts 
    [] 
    (let [inputmap (.getInputMap (.getContentPane frame) JComponent/WHEN_IN_FOCUSED_WINDOW) 
     actionmap (.getActionMap (.getContentPane frame)) 
     config (merge (read-clj "config/keybindings/site.clj") 
        (if (.exists (File. "config/keybindings/user.clj")) 
        (if-let [my-config ((read-clj "config/keybindings/user.clj") me)] 
         my-config {})))] 
    (doseq [[k {shortcut-type :type shortcut-info :config}] config 
      :let [sym-name (str (gensym)) 
       fun (case shortcut-type 
          :plot #(process-display-config shortcut-info) 
          :function (dealias-keystroke-config-keyword shortcut-info) 
          #{})]] 

     (.put inputmap (KeyStroke/getKeyStroke k) sym-name) 
     (.put actionmap sym-name (action fun))))) 

Um Platz zu sparen, habe ich den Code für dealias-keystroke-config-keyword und process-display-config nicht hinzugefügt. Ich werde klarstellen, dass die Schlüsselwörter: "Nächster Tag", "Vortag", "Nächste Stunde" und "Vorherige Stunde" dazu führen, dass die Analyse um 24, -24, 1 bzw. -1 Stunden verschoben wird.

Das Problem, mit dem ich bin, ist, dass meine Versuche, diese Befehle an die Pfeiltasten zu binden, nicht funktionieren. Immer wenn ich sie an andere Nicht-Pfeil-Tasten binde, funktioniert alles wie geplant. Aber wenn ich versuche, sie an die Pfeiltasten zu binden, fängt das "X:" -Spinner das Schlüsselereignis ab und es wird nicht ausgelöst ... stattdessen führen UP und DOWN nur dazu, dass sich der X-Spinner nach oben und unten bewegt.

Wenn ich die Spinner deaktivieren, funktionieren die Tastatureingaben, aber das widerspricht dem Zweck der Spinner. Wenn ich die Spinner deaktiviere, drücke die Pfeiltasten und aktiviere sie wieder, dann funktioniert es, aber ich muss sie manuell über die REPL deaktivieren, dann gehe zurück zum Anwendungsfenster, drücke die Pfeiltasten und reaktiviere sie erneut meine REPL. Keine Lösung.

Der Versuch, die Tastenbindungen von den Spinnern zu entfernen, ergibt nicht viel - es sagt, es gibt keine Tastenbindungen!

(.allKeys (.getInputMap x-panes-spinner)) => nil 

durch die Kinder der Spinner zu gehen ist nicht hilfreich entweder in dieser Hinsicht:

(doseq [comp (.getComponents x-panes-spinner) 
     k (.allKeys (.getInputMap comp))] 
    (prn [(.getName comp) (.getKeyCode k)])) 

    => ["Spinner.nextButton" 32] 
    => ["Spinner.nextButton" 32] 
    => ["Spinner.nextButton" 10] 
    => ["Spinner.nextButton" 10] 
    => ["Spinner.previousButton" 32] 
    => ["Spinner.previousButton" 32] 
    => ["Spinner.previousButton" 10] 
    => ["Spinner.previousButton" 10] 

32 und 10 auf die Leertaste entsprechen und Schlüssel eingeben, damit mir nicht helfen.

Ich bin ziemlich zuversichtlich, dass ich einen MouseListener hinzufügen könnte, um die Spinner nur zu aktivieren/deaktivieren, wenn sie eingegeben werden, aber ich würde sie eher davon abhalten, auf die Pfeilereignisse zu reagieren, anstatt sie dynamisch aktivieren und deaktivieren zu lassen .

Irgendwelche Ideen, StackOverflow? Ich würde auf diesem einen ratlos sein.

Antwort

3

Der Versuch, die Tastenbindungen von den Spinnern zu entfernen, ergibt nicht viel - es sagt, es gibt keine Tastenbindungen!

Eine Liste aller Bindungen für jede Swing-Komponente finden Sie unter Key Bindings.

Im Folgenden werden dann die Bindungen für den Spinner deaktivieren:

InputMap im = spinner.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
im.put(KeyStroke.getKeyStroke("DOWN"), "none"); 
im.put(KeyStroke.getKeyStroke("UP"), "none"); 
+0

Dies scheint sehr gut zu funktionieren! Ich habe immer noch Probleme damit, dass ETWAS linke und rechte Tastenanschläge abfängt, aber das weist mich in die richtige Richtung. Vielen Dank! – sleepysilverdoor

Verwandte Themen