# KeyListener funktioniert nicht



## Maxim6394 (20. Okt 2011)

ich versuch grade die lektionen aus einem buch zu machen und bin bei nem fenster das dich durch eine tastatureingabe schließen soll.
diesen code hab ich übernommen:


```
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;

public class frame
extends Frame
implements KeyListener
{

public static void main (String[] args)

{


frame wnd=new frame();


}


	public frame()

	{
		super ("Nachtrichtentransfer");

		setBackground(Color.lightGray);
		setSize(500,400);
		setLocation(200,100);
		setVisible(true);
	}



	public void keyPressed(KeyEvent event)
	{
	if (event.getKeyCode() == KeyEvent.VK_ESCAPE) 
		{
		setVisible(false);
		dispose();
		System.exit(0);
		}
	}

	public void paint(Graphics g)
	{
	g.setFont(new Font("Serif",Font.PLAIN,18));
	g.drawString("Zum beenden ESC drücken",10,50);
	}


	public void keyReleased(KeyEvent event)
	{}

	public void keyTyped(KeyEvent event)
	{}

}
```

es wird keine fehlermeldung ausgegeben, aber das fenster reagiert auf das drücken von escape überhaupt nicht. hat jemand eine idee?


----------



## ARadauer (20. Okt 2011)

dein frame ist ein keyListener, der braucht aber auch einen.
Also musst du einem frame sich selbst als keylistener hinzufügen... in der main

frame wnd = new frame();
wnd.addKeyListener(wnd);

und Klasen immer groß schreiben und ich würd keine Namen verwenden die es schon gibt... wie Frame..


----------



## Maxim6394 (20. Okt 2011)

hab jetzt wnd.addKeyListener(wnd); in main eingefügt, es geht aber noch immer nicht.


----------



## Apfelsinenkern (20. Okt 2011)

Der Fehler ist ganz klar: Du hast eine Klasse erzeugt, die von der Framklasse erbt, und erzeugst ein weiteres fenster.... lösch das frame, das du erzeugen willst raus, und schreib: this.addKeyListener(this);
Es macht nämlich keinen sinn, zwei frames hier zu benutzen ;D

Achja, schreibs nich in die main, sondern in den konstruktor, find ich is besser...


----------



## SlaterB (20. Okt 2011)

> Du hast eine Klasse erzeugt, die von der Framklasse erbt, und erzeugst ein weiteres fenster.... 

hmm, nein?

---------

bei mir gehts,
schreibe in alle Listener-Methoden eine Ausgabe um zu testen ob zumindest irgendwo irgendwelche Events ankommen,
teste auch andere Tasten der Tastatur,

in Swing bei JPanel in JFrame muss man erst (nach setVisible(true) ) requestFocus() bzw. requestFocusInWindow() und ähnliches fürs JPanel aufrufen

KeyBindings ist noch eine Alternative



> How to Write a Key Listener
> 
> Key events indicate when the user is typing at the keyboard. Specifically, key events are fired by the component with the keyboard focus when the user presses or releases keyboard keys. For detailed information about focus, see How to Use the Focus Subsystem.
> Note:
> ...


How to Write a Key Listener (The Java™ Tutorials > Creating a GUI With JFC/Swing > Writing Event Listeners)


----------



## Apfelsinenkern (20. Okt 2011)

```
frame wnd=new frame();


}


	public frame()

	{
		super ("Nachtrichtentransfer");

		setBackground(Color.lightGray);
		setSize(500,400);
		setLocation(200,100);
		setVisible(true);
	}
```


Was ich meine , ist ein Schönheitsfehler, der das ganze unübersichtlich macht -.-

Er hat zwei Frames, das eine aus der Klasse, und das andere (wnd). Er setzt aber nicht wnd sichtbar, sondern das andere Fenster, gibt aber wiederum wnd den KeyListener.... Verstehst du was ich meine?

Wenn ich damit falsch liegen soll, dann korrigiere mich...


----------



## hdi (20. Okt 2011)

> Er hat zwei Frames, das eine aus der Klasse, und das andere (wnd).



Nein, er hat nur ein Frame. _wnd == this_. Ist schon alles in Ordnung in dem Code. Die Variable wnd ist lediglich überflüssig, da sie nicht weiter verwendet wird. Man könnte auch nur 
	
	
	
	





```
new frame();
```
 schreiben in der main, wär das selbe.


----------



## Maxim6394 (20. Okt 2011)

ich hab jetzt in jedes key event System.out.println("asdf"); geschrieben. es erfolgt auch eine ausgabe, tastureingaben werden also erkannt. das problem liegt an 
	
	
	
	





```
if (event.getKeyCode() == KeyEvent.VK_ALL_CANDIDATES) 
		{
		System.out.println("asdf");
		setVisible(false);
		dispose();
		System.exit(0);
		}
```
da passiert nämlich gar nichts, also wird wohl nicht erkannt dass die escape taste gedrückt wird.


----------



## SlaterB (20. Okt 2011)

@Apfelsinenkern
es gibt die Klasse frame und davon wird ein Objekt erzeugt, dieses eine Objekt ist ein JFrame, weil frame davon erbt,
ob bereits im Konstruktor dieses eine Objekt geändert wird, oder erst in der main-Methoden, nachdem unter der Variablen wnd abgelegt, 
ist relativ egal

das passt schon, vom schlechten Klassennamen abgesehen

-----

> da passiert nämlich gar nichts, also wird wohl nicht erkannt dass die escape taste gedrückt wird. 

gib doch bitte den KeyCode aus, vergleiche ihn mit der statischen Variable, also gib diese auch aus

edit: ok, Quellcode wurde einfach zwischenzeitlich geändert..


----------



## hdi (20. Okt 2011)

Es heißt KeyEvent.VK_ESCAPE


----------



## Maxim6394 (20. Okt 2011)

ach ja, ich hatte das testweise ersetzt weil ich dachte dass VK_ALL_CANDIDATES alle tasten sind. jetzt funktioniert es wohl ordnungsgemäß.


----------



## ARadauer (20. Okt 2011)

Maxim6394 hat gesagt.:


> ich hab jetzt in jedes key event System.out.println("asdf"); geschrieben. es erfolgt auch eine ausgabe, tastureingaben werden also erkannt. das problem liegt an
> 
> 
> 
> ...



naja wenn mal asdf ausgegeben wird... sollte das System.exit(0); sein übriges tun... ähmn wie startest du das programm? beim mir gehts


----------



## Apfelsinenkern (20. Okt 2011)

@slater b: ok, da bin ich eines besseren belehrt worden  wieder was gelernt. Ich arbeite eh nur mit javax.swing, mit awt komponenten kenn ich mich ned so aus


----------



## hdi (20. Okt 2011)

> Ich arbeite eh nur mit javax.swing, mit awt komponenten kenn ich mich ned so aus


Ein KeyListener ist keine Komponente, und es gibt kein Pendant aus dem Swing-Package. Auch in Swing-Applikationen benutzt man die AWT-Listener und -Events. Und rate mal, wovon JFrame ableitet  Es ist nur so, dass man die Widgets (Fenster, Buttons, usw) nicht durchmischen sollte - aber AWT und Swing gehen Hand in Hand.


----------



## SlaterB (20. Okt 2011)

es ist wohl eher Frame vs JFrame gemeint, 
das Problem mit evtl. doppelten Objekten bei Vererbung ist allerdings auch davon bzw. generell von GUI unabhängig  ,
bei jeder Klasse besser genau zu durchschauen


----------



## Maxim6394 (20. Okt 2011)

ich hab jetzt nochmal bisschen was anderes versucht:


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;





public class window
extends Window


{

	public static void main(String[] args)

	{

	window wnd=new window();
	wnd.setSize(300,200);
	wnd.setVisible(true);
	
	
	}
	
	public window()
		{
		super(new Frame());
		setBackground(Color.white);
	addKeyListener(new MyKeyListener());

		}

	public void paint(Graphics g)

	{
		
	}


	class MyKeyListener
		extends KeyAdapter
		{
		
		public void keyPressed(KeyEvent event)
			{
			System.out.println("asdf");
			
			}	
		
		}
	
}
```

da wird jetzt auch keinerlei eingabe erkannt, es wird nichts ausgegeben.


----------



## SlaterB (20. Okt 2011)

http://www.java-forum.org/awt-swing-swt/527-keylistener-funkt-window-frame-schon.html


----------



## Maxim6394 (20. Okt 2011)

hat sich erledigt.


----------



## Gast2 (20. Okt 2011)

Du erstellst in der main auch nen neuen Frame, du musst da aber ne Instanz deiner Klasse window erstellen.

EDIT:
code wegeditiert :/


----------



## SlaterB (20. Okt 2011)

es gibt auch JAVA-Tags statt CODE-Tags...

im Moment erzeugst du direkt ein Frame-Objekt, die Klasse window ist bis auf main-Methode unbeteiligt


----------



## ARadauer (20. Okt 2011)

ARadauer hat gesagt.:


> und Klasen immer groß schreiben und ich würd keine Namen verwenden die es schon gibt... wie Frame..




```
public class window
extends Window
```
Ach s***** drauf, wozu geb ich mir überhaupt Mühe...


----------

