# KeyListener - Thread Problem



## Askadi (22. Okt 2010)

Hallo habe mal wieder ein kleines Problem das ich einfach nicht verstehen kann... hier der gekürzte Quelltext dazu:


```
package Blemmer_v2;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class blemmver_v2 {

	/**
	 * @param args
	 */
	
	static ImageIcon blemmer_img = new ImageIcon("src/BLEMMER_r.gif");
	static JLabel blemmer = new JLabel(blemmer_img);	
	static JFrame window = new JFrame("Blemmer V2");
	
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub

		
		window.setBounds(10,200,800,400);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	
		
		Container cont = window.getContentPane();
		cont.setLayout(null);
		
		
		// Blemmer Label
		
		
		blemmer.setBounds(0,250,50,100);
		blemmer.setBackground(Color.black);
		cont.add(blemmer);
		
		
		
		
		
		
		blemmer.addKeyListener(new KeyAdapter()
		{
			 public void keyPressed(KeyEvent event)
			 {
		
				 

				 
				 // hier funktioniert leider nichts
				 if (event.getKeyCode() == KeyEvent.VK_SPACE) 
				 {
					 animation();
				 }
			 }
		});
		
		window.setVisible(true);
		
		
		
		
		
		// hier funktioniert alles wie es soll
		animation();
	}
	
	
	public static void animation()
	{
	
		try 
		{
			
				int sprung = 100;
				
				// hoch springen
				for(int i = 0; i< sprung;i++)
				{
					blemmer.setBounds(blemmer.getX(),blemmer.getY()-1, 50, 100);
					Thread.sleep(12);
				}
				
				// runter fallen
				for(int j = sprung;j >= 0;j--)
				{
					blemmer.setBounds(blemmer.getX(),blemmer.getY()+1, 50, 100);
					Thread.sleep(12);
				}
			
						
			
		} 
		catch (InterruptedException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
```

Das Programm soll einfach nur eine Sprung animation darstellen also ein label soll mit leertaste springen können.

Wenn die animation() aufgerufen wird zur Laufzeit funktioniert das auch warum aber nicht im KeyListener?!


----------



## eRaaaa (22. Okt 2010)

Weil Listener-Codes von einem Thread ausgeführt wird, der für das Zeichnen und Darstellen der Komponenten verantwortlich ist(The Event Dispatch Thread (The Java™ Tutorials > Creating a GUI With JFC/Swing > Concurrency in Swing))
Durch dein sleep legst du diesen nun auch noch schlafen...Lösung: ein neuer Thread muss her!
Ausserdem hat das Label evtl. auch nicht den Fokus!
Probiere mal:

```
package Blemmer_v2;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class blemmver_v2 {

	/**
	 * @param args
	 */

	static ImageIcon blemmer_img = new ImageIcon("src/BLEMMER_r.gif");
	static JLabel blemmer = new JLabel(blemmer_img);
	static JFrame window = new JFrame("Blemmer V2");

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		window.setBounds(10, 200, 800, 400);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		Container cont = window.getContentPane();
		cont.setLayout(null);

		// Blemmer Label

		blemmer.setBounds(0, 250, 50, 100);
		blemmer.setBackground(Color.black);
		cont.add(blemmer);

		blemmer.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent event) {
				// hier funktioniert leider nichts
				if (event.getKeyCode() == KeyEvent.VK_SPACE) {
					new Thread(new Runnable() {
						@Override
						public void run() {
							animation();  //evtl. auch direkt lieber einen swing-timer benutzen, das erspart auch das sleep rumgegurke :)
						}
					}).start();
				}
			}
		});

		window.setVisible(true);

		// hier funktioniert alles wie es soll
		animation();
		blemmer.requestFocus();
	}

	public static void animation() {

		try {

			int sprung = 100;

			// hoch springen
			for (int i = 0; i < sprung; i++) {
				
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						blemmer.setBounds(blemmer.getX(), blemmer.getY() - 1, 50, 100);
					}
				});
				Thread.sleep(12);
			}

			// runter fallen
			for (int j = sprung; j >= 0; j--) {
				
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						blemmer.setBounds(blemmer.getX(), blemmer.getY() + 1, 50, 100);
					}
				});
				Thread.sleep(12);
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
```
(auch den Kommentar beachten !)


----------



## Askadi (22. Okt 2010)

Sowas in der Art hab ich mir fast schon gedacht danke für die Hilfe ist zwar fast etwas zu viel für meinen Wissensstand aber da kann ich mich reinlesen denk ich


----------

