2014-11-05 128 views
0

我正在尝试使用Java进行图形编程,并且尝试了一些练习,以便让汽车在一帧中来回移动。然后,如果按下向上或向下箭头键,我想让它变快或变慢。但是,我似乎无法正确添加按键侦听器。为了测试我的代码,我只是试图向命令提示符输出一条消息。任何帮助将不胜感激!Java:向JFrame添加密钥监听器

代码编译并按原样运行。我得到一辆车在车架上来回走动。唯一不起作用的是关键听众。

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

public class Racing extends JFrame 
{ 
    public static class Car extends JComponent implements ActionListener 
    { 
     int x=0; 
     int y=0; 
     int delta = 10; 
     Timer timer; 
     int z = 300; 

     public Car() 
     { 
      timer = new Timer(20,this); 
      timer.start(); 

      addKeyListener(new KeyAdapter() 
      { 
       @Override 
       public void keyPressed(KeyEvent e) 
       {   
        if(e.getKeyCode() == KeyEvent.VK_UP) 
         System.out.println("The up key was pressed!"); 
       } 
      }); 
     } 

     public void paint(Graphics g) 
     { 
      super.paintComponent(g); 

      y = getHeight(); 
      z = getWidth(); 

      g.setColor(Color.BLUE); 
      g.fillRect(0, 0, z, y); 

      Polygon polygon = new Polygon(); 
      polygon.addPoint(x + 10, y - 20); 
      polygon.addPoint(x + 20, y - 30); 
      polygon.addPoint(x + 30, y - 30); 
      polygon.addPoint(x + 40, y - 20); 

      g.setColor(Color.BLACK); 
      g.fillOval(x + 10, y - 11, 10, 10); 
      g.fillOval(x + 30, y - 11, 10, 10); 
      g.setColor(Color.GREEN); 
      g.fillRect(x, y - 21, 50, 10); 
      g.setColor(Color.RED); 
      g.fillPolygon(polygon); 
      g.setColor(Color.BLUE); 
     } 

    public void actionPerformed(ActionEvent e) { 
     x += delta; 
     if (x > z-40) { 
      delta *= -1; 
      x = (z-40); 
     } else if (x < 0) { 
      delta *= -1; 
      x = 0; 
     } 

     repaint(); 
    } 

    } 

    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("Racing"); 
     frame.setPreferredSize(new Dimension(600,300)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.add(new Car()); 
     frame.setVisible(true); 
     frame.setFocusable(true); 
    } 
} 

回答

3

简短的回答是不要,涉及的问题太多。

而是使用键绑定API。见How to Use Key Bindings更多细节

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Polygon; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.KeyStroke; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Racing extends JFrame { 

    public static class Car extends JComponent implements ActionListener { 

     int x = 0; 
     int y = 0; 
     int delta = 10; 
     Timer timer; 
     int z = 300; 

     public Car() { 
      timer = new Timer(20, this); 
      timer.start(); 

      InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "goingUp"); 

      ActionMap am = getActionMap(); 
      am.put("goingUp", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("The up key was pressed!"); 
       } 
      }); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      y = getHeight(); 
      z = getWidth(); 

      g.setColor(Color.BLUE); 
      g.fillRect(0, 0, z, y); 

      Polygon polygon = new Polygon(); 
      polygon.addPoint(x + 10, y - 20); 
      polygon.addPoint(x + 20, y - 30); 
      polygon.addPoint(x + 30, y - 30); 
      polygon.addPoint(x + 40, y - 20); 

      g.setColor(Color.BLACK); 
      g.fillOval(x + 10, y - 11, 10, 10); 
      g.fillOval(x + 30, y - 11, 10, 10); 
      g.setColor(Color.GREEN); 
      g.fillRect(x, y - 21, 50, 10); 
      g.setColor(Color.RED); 
      g.fillPolygon(polygon); 
      g.setColor(Color.BLUE); 
     } 

     public void actionPerformed(ActionEvent e) { 
      x += delta; 
      if (x > z - 40) { 
       delta *= -1; 
       x = (z - 40); 
      } else if (x < 0) { 
       delta *= -1; 
       x = 0; 
      } 

      repaint(); 
     } 

    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Racing"); 
       frame.setPreferredSize(new Dimension(600, 300)); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.pack(); 
       frame.add(new Car()); 
       frame.setVisible(true); 
       frame.setFocusable(true); 
      } 
     }); 
    } 
} 

另外,不要从paintsuper.paintComponent,你基本上打破了整个涂料链。相反,覆盖paintComponent方法本身...

+0

谢谢!那是我想要考虑的方向。我买了一本Java编程书,里面有一些图形信息,但它指出我在这方面有不同的方向。打破涂料链有什么后果? – 2014-11-05 07:04:01

+0

你可能最终会出现奇怪的绘画工件或根本没有被绘的东西 – MadProgrammer 2014-11-05 08:42:53