Input/Output Keylistener Aktiv schalten

AtlanTK

Mitglied
Hi
ich habe ein Problem mit einem JFrame in dem ich 2 JPanels angelegt habe.
In einem Panel ist ein Keylistener, der auf Pfeiltasten reagiert, und in dem Anderen ein Textfeld und ein Button.
Wenn ich starte, ist der Keylistener aktiv und reagiert auf Tastenanschläge. Wenn nun aber der Button oder das Textfeld geklickt wird, kann ich das erste Panel nicht wieder aktivieren.
Ich suche nach einer Möglichkeit den Keylistener wieder per Klick auf einen Button, oder in das richtige Panel wieder aktiv zu schalten, oder durchgehend aktiv zu halten.

Hier der JFrame in dem alles drinnen ist.

Code:
public class GameWindow extends JFrame {

	private String title;
	private final int breite, hoehe;
	private Dimension dim;
	private GamePanel panel;
	JButton button;
	JTextField eingabe;
	JPanel panel2;

	public GameWindow(String title, int breite, int hoehe) {

		super(title);
		this.breite = breite;
		this.hoehe = hoehe;
		this.title = title;
		dim = new Dimension(breite, hoehe);

		setMaximumSize(dim);
		setMinimumSize(dim);
		setPreferredSize(dim);
		setAlwaysOnTop(true);
		setResizable(false);
		setLocationRelativeTo(null);
		setLayout(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		panel2 = new JPanel();
		panel2.setLayout(null);
		panel2.setBounds(10, 400, 600, 80);
		add(panel2);

		Font schrift = new Font("Serif", Font.BOLD, 15);
		Icon x = new ImageIcon(getClass().getResource("raster.png"));
		
		 button = new JButton("Hallo Welt");
		 button.setBounds(0, 0, 150, 50);
		 button.setFont(schrift);
		 button.addActionListener(new ButtonListener());
		 button.setToolTipText("Schreibt den Text aus der Checkbox in diesen Button.");
		 panel2.add(button);

		eingabe = new JTextField();
		eingabe.setBounds(160, 0, 200, 50);
		eingabe.setFont(schrift);
		eingabe.addCaretListener(new ButtonListener());

		panel2.add(eingabe);

		 panel = new GamePanel();
		 panel.setBackground(Color.GRAY);
		 panel.setBounds(0, 0, 600, 395);
		 panel.setFocusable(true);
		 add(panel);
		 
		 JPanel panel3 = new JPanel();
		 panel3.setBounds(0, 0, 600, 395);
		 JLabel picture = new JLabel(x);
		 picture.setBackground(Color.BLUE);
		 picture.setBounds(0, 0, 600, 395);
		 panel3.add(picture);
		 panel.add(panel3);

		setVisible(true);
	}

	private class ButtonListener implements ActionListener, CaretListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			button.setText(eingabe.getText());
		}

		@Override
		public void caretUpdate(CaretEvent e) {
		}
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getBreite() {
		return breite;
	}

	public int getHoehe() {
		return hoehe;
	}

}

Wäre echt geil, wenn mir da jemand helfen könnte.
(ist für ein kleines Spiel was ich versuche mit ein paar Freunden zu programmieren)
 
Damit ein KeyListener reagiert muss die Komponente den Fokus haben. Den Fokus immer wieder zurückzusetzen ist nicht so schön, arbeite da lieber mit KeyBindings/InputMap.
 
Damit ein KeyListener reagiert muss die Komponente den Fokus besitzten. Jemand oder etwas müsste also requestFocus() auf der Komponente aufrufen, z.B. per Mausklick auf die Komponente.
Vermutlich wäre für diesen Fall Key Bindings besser geeignet als ein KeyListener.
Abgesehen davon ist in den Code nichts von einem KeyListener zu sehen.
 
Damit ein KeyListener reagiert muss die Komponente den Fokus besitzten. Jemand oder etwas müsste also requestFocus() auf der Komponente aufrufen, z.B. per Mausklick auf die Komponente.
Vermutlich wäre für diesen Fall Key Bindings besser geeignet als ein KeyListener.
Abgesehen davon ist in den Code nichts von einem KeyListener zu sehen.

Der wird in panel auf selbiges geschrieben.
 
Hi
ich habe jetzt einen inputMap Eintrag erstellt, auf meinem panel.
Leider werden bei fokusieren einer anderen JComponent die events nicht mehr aufgerufen.
Code:
panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
	panel.getActionMap().put("right", new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			System.out.println("left");
			panel.getMoveEntityThread().keyPressed("x", 1);
		}
	}
);

Um die actions immer auf zu rufen, müsste ich jetzt alle anderen richtungs-events mit none überschreiben, oder?

Code:
panel2.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("UP"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "none");
Habe es so versucht: geht auch nicht.
 
Zuletzt bearbeitet:
Zunächst mal ein Hinweis: Gib den Variablen sprechende Namen, vor allem wenn es sich um "bedeutende" Variablen handelt: panel ==> gamePanel
Hi
ich habe jetzt einen inputMap Eintrag erstellt, auf meinem panel.
Leider werden bei fokusieren einer anderen JComponent die events nicht mehr aufgerufen.
Eine Komponente besitzt verschiedene InputMaps, für Dich Interessant:
Code:
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
Das ja auch reagiert werden soll, wenn die Komponente nicht den Fokus hat.

Um die actions immer auf zu rufen, müsste ich jetzt alle anderen richtungs-events mit none überschreiben, oder?

Code:
panel2.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("UP"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "none");
panel2.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "none");
Habe es so versucht: geht auch nicht.
Ist ja auch Schmarrn, bei einem Panel sind für diese KeyStroke ohnehin keine Aktionen in der InputMap enthalten.
 

Zurück
Oben