2016-04-18 16 views
3

Das heutige Problem rasselt mir durch den Kopf: Ich versuche ein rotes Rechteck zu zeichnen, das sich bewegt, wenn der Benutzer auf das Leerzeichen drückt. Das Problem ist, dass, wenn ich die Leerstelle drücke, das Rechteck sich nicht bewegt. Irgendwelche Ideen, warum und wie ich dieses Problem beheben könnte?Wie kann ich Animation mit KeyBoard-Eingabe in JAVA ausführen lassen?

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.*; 

public class Animation extends JPanel implements ActionListener, KeyListener{ 

    int x = 0, y = 0, velx=0; 

    public Animation(){ 
     addKeyListener(this); 
     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); 
    } 

    public static void main(String args[]){ 
     JFrame frame = new JFrame("Animation Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     frame.setSize(500, 500); 
     Animation a = new Animation(); 
     frame.add(a); 

    } 

    public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
     g.setColor(Color.BLACK); 
     g.fillRect(0, 0, 500, 500); 
     g.setColor(Color.RED); 
     g.fillRect(x, 50, 30, 20); 
     } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // TODO Auto-generated method stub 
     x = x + velx; 
     repaint(); 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     // TODO Auto-generated method stub 
     int keyCode = e.getKeyCode(); 
     if(keyCode == e.VK_SPACE){ 
      velx = 2; 
     } 

    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

} 
+0

Warum importieren Sie AWT und Swing? Benutze entweder das eine oder das andere. Auch wenn Sie die Tags "awt" und "swing" zu Ihrer Frage hinzufügen, erhalten Sie möglicherweise mehr Feedback :) –

+0

Ja, grundsätzlich wie in der Antwort unter "actionPerformed" wird wahrscheinlich nie aufgerufen werden. Sie müssen die Aktualisierungslogik in die 'KeyListener'-Ereignisse einfügen. – Gorbles

+0

[Verwenden von Tastenkombinationen] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) – MadProgrammer

Antwort

1

Die folgenden Änderungen an Ihrem Code vorgenommen. Durch Drücken der Rücktaste sollte nun das Rechteck verschoben werden.

  1. Fügen Sie den KeyListener zu JFrame hinzu.
  2. Änderungen an der KeyBoard-Ereignis-Listener-Methode.

Code:

public class Animation extends JPanel implements ActionListener, KeyListener{ 

int x = 0, y = 0, velx=0; 

public Animation(){ 
    addKeyListener(this); 
    setFocusable(true); 
    setFocusTraversalKeysEnabled(false); 
} 

public static void main(String args[]){ 
    JFrame frame = new JFrame("Animation Test"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
    frame.setSize(500, 500); 
    Animation a = new Animation(); 
    frame.add(a); 
    frame.repaint(); 
    frame.addKeyListener(a); 

} 

protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, 500, 500); 
    g.setColor(Color.RED); 
    g.fillRect(x, 50, 30, 20); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    // TODO Auto-generated method stub 
    x = x + velx; 
} 

@Override 
public void keyTyped(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void keyPressed(KeyEvent e) { 
    // TODO Auto-generated method stub 
    int keyCode = e.getKeyCode(); 
    if(keyCode == e.VK_SPACE){ 
     velx = 2; 
     x = x + velx; 
    } 
    repaint(); 
} 

@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 

} 

} 
+0

[Verwenden von Tastenkombinationen] (http://docs.oracle.com/ javase/tutorial/uiswing/misc/keybinding.html) und [Anfängliche Threads] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html); "PaintComponent" muss nicht öffentlich sein. – MadProgrammer

+0

@MadProgrammer Edited. Danke, dass du es gezeigt hast. – alphablue

3

Das Problem ist KeyListener ist nur ein Schmerz in der ... Code.

Es reagiert nur auf Schlüsselereignisse, wenn die Komponente, für die es registriert ist, fokussierbar UND mit Tastaturfokus ist. Das Problem ist, der Fokus ändert sich und es ist ein Schmerz zu verwalten und zu kontrollieren.

Stattdessen sollten Sie die Key Bindings API werden, das entworfen wurde, um dieses Problem zu lösen helfen

Es gibt viele Beispiele von Tastenbelegungen auf SO, vielleicht so etwas wie this helfen könnten