Swing globale "Key Bindings" für Swing-Applikation

Curry

Aktives Mitglied
Moin Moin!

Ich würde meiner Swing-Applikation gerne globale "Key Bindings" verleihen. Also "Key Bindings" die aktiviert werden können, egal welche Swing-Komponente im Fokus ist. Also beispielsweise ESC beendet das Programm.

Ich dachte das mit einer InputMap und ActionMap für das Hauptfenster lösen zu können, aber für JFrame gibt es weder die Methode "getInputMap()", noch "getActionMap()".

Wie geht's denn dann? Irgend einem JLabel die Aktionen geben, das geht natürlich auch, finde ich aber unschön.

Würde mich über eure Hilfe freuen!
 
Hi,

wenn man's weiß eigentlich ganz einfach:
Java:
public class EscapeFrame extends JFrame {

	public EscapeFrame() {
		//[...]
		Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
// AWTEventListener hier als anonyme Klasse
			@Override
			public void eventDispatched(AWTEvent arg0) {
				KeyEvent keyEvent = (KeyEvent) arg0;
				if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) {
					System.exit(0);
				}

			}
		}, AWTEvent.KEY_EVENT_MASK);
	}
}

man implementiert einen Listener für alle Events mittels
Code:
Toolkit.getDefaultToolkit().addAWTEventListener(AWTEventListener listener, long eventMask)
schränkt ihn mit der Maske
Code:
long eventMask
aber wieder auf TasturEvents (
Code:
AWTEvent.KEY_EVENT_MASK
) ein und kann dann mittels Cast des AWTEvents
Code:
(KeyEvent) arg0
und Vergleich auf
Code:
VK_ESCAPE
das gewünschte Verhalten implementieren.
Das geht natürlich für alle möglichen Tastatur-Keys und auch für andersartige Events (z.B. Maus).

Grüße
Momolin
 
[TIPP]Versuch's trotzdem erst mit den InputMap/ActionMaps der ContentPane des JFrames[/TIPP]

Das mit dem Listener ist ... SEHR low-level (und IMHO unangebracht). Von der möglichen SecurityException mal abgesehen...
 
Moin!

Ich habe es mit dem ContentPane gemacht. Allerdings gibt es ein sehr merkwürdiges Problem. Wenn ich die Tasten F1 und F2 verwende funktioniert die F2-Funktion nur solange F1 noch nie gedrückt wurde. Wenn ich statt F2 die Taste F3 verwende, damm tritt das Problem nicht auf und die F3-Funktion funktioniert immer.

Hat da jemand eine Idee?

Java:
JPanel content = new JPanel();

content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F1"), "aaa");
content.getActionMap().put("aaa", actionToggleFilter);

content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F2"), "bbb");
content.getActionMap().put("bbb", actionToggleTabbedPane);

setContentPane(content);
 
Ein KSKB wäre nicht schlecht. Es gibt aber einige "Hotkeys" (unter Windows z.B. auch "Alt") die den Fokus ins Menü verlagern, vielleicht ist es was in der Richtung...
 
Hmmmm!! Ich habe mal ein solches Beispiel gebastelt. Dummerweise funktioniert es hier einwandfrei. ;-)

D.h. es gibt ein Fehler bei mir im Programm. Nur wo ist die Frage? ....Code nicht gapasted, da zu viel

Java:
package test;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import org.jdesktop.swingx.JXFrame;

public class Test extends JXFrame {

	public static void main(String[] args) {
		Test obj = new Test();
		obj.setVisible(true);
	}

	JLabel labelA, labelB;
	ToggleLabelA actionA;
	ToggleLabelB actionB;

	public Test() {
		super("KeyBinding");
		setDefaultCloseOperation(JXFrame.EXIT_ON_CLOSE);

		actionA = new ToggleLabelA();
		actionB = new ToggleLabelB();

		JPanel content = new JPanel();

		content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F1"), "aaa");
		content.getActionMap().put("aaa", actionA);

		content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F2"), "bbb");
		content.getActionMap().put("bbb", actionB);

		setContentPane(content);

		initComponents();

		pack();
		setLocationRelativeTo(null);

	}

	private void initComponents() {

		GridBagConstraints c = new GridBagConstraints();
		setLayout(new GridBagLayout());

		// ########################################################################
		// Menu
		// ########################################################################
		JMenuBar menuBar = new JMenuBar();
		menuBar.add(createFileMenu());
		setJMenuBar(menuBar);

		// ########################################################################
		// Content
		// ########################################################################
		labelA = new JLabel("Hallo Welt!");
		c.gridx = 0;
		c.gridy = 0;
		add(labelA, c);

		labelB = new JLabel("Hallo Du!");
		c.gridx = 0;
		c.gridy = 1;
		add(labelB, c);

	}

	// ###############################################################################################
	// MENU
	// ###############################################################################################
	private JMenu createFileMenu() {
		JMenu ret = new JMenu("File");

		JMenuItem miA = new JMenuItem(actionA);
		miA.setText("toggle A");
		ret.add(miA);

		JMenuItem miB = new JMenuItem(actionB);
		miB.setText("toggle B");
		ret.add(miB);

		return ret;
	}


	// ###############################################################################################
	// Action
	// ###############################################################################################
	class ToggleLabelA extends AbstractAction {

		boolean status = true;

		@Override
		public void actionPerformed(ActionEvent e) {
			if (status) {
				labelA.setText("Hallo Mond!");
				status = false;
			} else {
				labelA.setText("Hallo Erde!!!");
				status = true;
			}

		}
	}

	class ToggleLabelB extends AbstractAction {

		boolean status = true;

		@Override
		public void actionPerformed(ActionEvent e) {
			if (status) {
				labelB.setText("Hallo Sie!");
				status = false;
			} else {
				labelB.setText("Hallo Du!!!");
				status = true;
			}

		}
	}
}
 

Zurück
Oben