2013-03-04 81 views
0

我想要一個圓來移動鍵盤的輸入。我根本無法移動對象。有人能幫我弄清楚什麼是錯的?這裏是我的代碼:Java對象移動

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JPanel; 


public class AlienInvader extends JPanel implements KeyListener{ 

    Constants constant = new Constants(); 

    public void update() { 
     constant.x += constant.xvel; 
     addKeyListener(this); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(Color.MAGENTA); 
     g.fillOval(constant.x, constant.y, 30, 30); 
     repaint(); 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     System.out.println(constant.x); 
     switch(e.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      constant.xvel = -1; 
      break; 
     case KeyEvent.VK_RIGHT: 
      constant.xvel = 1; 
      break; 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     switch(e.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      constant.xvel = -1; 
      break; 
     case KeyEvent.VK_RIGHT: 
      constant.xvel = 1; 
      break; 
     } 
    } 

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

    } 


} 

我不知道我在做什麼錯。我認爲這是因爲我沒有調用更新方法,但是當我在paintComponent中添加if語句(因此它只調用一次)並嘗試它時,我沒有運氣。

回答

3

首先,請不要在任何paintXxx方法中調用repaint。通常會調用Paint方法來響應repaint的調用,因此您正在創建一個討厭的,永無止境的,永不消耗資源地獄的循環。

其次,KeyListener只有當1-註冊到的組件被關注時才響應關鍵事件2-當它們註冊的組件具有焦點時。

在這種情況下,他們是一個糟糕的選擇。使用Key bindings代替

第三,您沒有提供preferredSize提示佈局管理器使用。這可能是也可能不是你的情況是壞事,但它可能是你組件將與一個尺寸爲0x0進行佈局

喜歡的東西....

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
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.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class MoveCircle { 

    public static void main(String[] args) { 
     new MoveCircle(); 
    } 

    public MoveCircle() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private int xDelta = 0; 
     private int keyPressCount = 0; 
     private Timer repaintTimer; 
     private int xPos = 0; 
     private int radius = 10; 

     public TestPane() { 
      InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      ActionMap am = getActionMap(); 

      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "pressed.left"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "pressed.right"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "released.left"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "released.right"); 

      am.put("pressed.left", new MoveAction(-2, true)); 
      am.put("pressed.right", new MoveAction(2, true)); 
      am.put("released.left", new MoveAction(0, false)); 
      am.put("released.right", new MoveAction(0, false)); 

      repaintTimer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        xPos += xDelta; 
        if (xPos < 0) { 
         xPos = 0; 
        } else if (xPos + radius > getWidth()) { 
         xPos = getWidth() - radius; 
        } 
        repaint(); 
       } 
      }); 
      repaintTimer.setInitialDelay(0); 
      repaintTimer.setRepeats(true); 
      repaintTimer.setCoalesce(true); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setColor(Color.RED); 
      g2d.drawOval(xPos, 0, radius, radius); 
      g2d.dispose(); 
     } 

     public class MoveAction extends AbstractAction { 

      private int direction; 
      private boolean keyDown; 

      public MoveAction(int direction, boolean down) { 
       this.direction = direction; 
       keyDown = down; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       xDelta = direction; 
       if (keyDown) { 
        if (!repaintTimer.isRunning()) { 
         repaintTimer.start(); 
        } 
       } else { 
        repaintTimer.stop(); 
       } 
      } 
     } 
    } 
} 

例如...