2016-05-23 8 views
0

私はガンと呼ばれるものを作成するコードを記述しようとしています。これを右または左に移動したいと考えています。私はKeyListenerActionListenerメソッドを実装しましたが、actionPerformedは機能しません。しかし、keyPressedメソッドが動作します。私が逃したアイデアは何ですか?ActionPerformedがカスタムコンポーネントで動作していません

public class Gun extends JPanel implements KeyListener, ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private static final int GUN_WIDTH = 100; 
    private static final int GUN_HEIGHT = 30; 
    private static final int GUN_UPPER_HEIGHT = 20; 
    private static final int GUN_UPPER_WIDTH = GUN_WIDTH/4; 
    int x, y; 
    int velX; 

    public Gun() { 
     x = 250 - GUN_WIDTH/2; 
     y = 500 - GUN_HEIGHT; 
     velX = 0; 
     addKeyListener(this); 
     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 

     int upperX = x + GUN_WIDTH/2 - GUN_UPPER_WIDTH/2; 
     int upperY = y - GUN_UPPER_HEIGHT; 

     g2d.setColor(Color.BLACK); 
     g2d.fillRect(x, y, GUN_WIDTH, GUN_HEIGHT); 
     g2d.fillRect(upperX, upperY, GUN_UPPER_WIDTH, GUN_UPPER_HEIGHT); 
    } 

    public void left() { 
     velX = -1; 
    } 

    public void right() { 
     velX = 1; 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     // TODO Auto-generated method stub 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_LEFT) { 
      left(); 
      System.out.println("LEFT"); 
     } 
     if (key == KeyEvent.VK_RIGHT) { 
      right(); 
      System.out.println("RIGHT"); 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 
    } 

    @Override 
    public void keyTyped(KeyEvent arg0) { 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     x += velX; 
     repaint(); 
    } 

    public static void main(String[] args) { 
     Gun gun = new Gun(); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setTitle("Game"); 
     frame.setLayout(new FlowLayout()); 

     gun.setPreferredSize(new Dimension(500, 500)); 

     frame.add(gun); 
     frame.setVisible(true); 
     frame.pack(); 
    } 

} 
+5

あなたは 'addKeyListener(this)'を使用していますが、あなたはどこでも 'addActionListener'のために同じことをしましたか? – Zircon

+2

'KeyListener'の代わりに[' Key Bindings'](https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)の使用を検討してください。 –

+0

@ Zircon私はそれが何か間違っていたという考えを持っていました。しかし、もう一つの問題があります。私が 'addActionListener(this)'をコンストラクタに入れようとすると、Eclipseは私にそうすることができないので、できません。このメソッドが存在しないように動作します。なぜどんなアイデア? – Mantas

答えて

0

actionPerformedメソッドを実行するには、そのオブジェクトのActionListenerを追加する必要があります。あなたがactionListenerを追加しなかったので、あなたはactionPerformedメソッドを決して実行しません。アクションリスナーに

チェックするJavaチュートリアル:actionPerformedメソッドを実行するにはhttps://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

0

は、対応するオブジェクトにActionListenerを追加する必要があります。しかし、JPanelクラスにはaddActionListenerというメソッドはありません。

あなたのコードを見ると、ActionListenerインターフェイスを実装する必要はありません。その後、actionPerformedメソッドを取り除くことができます。 actionPerformedメソッドの中にコードをコピーし、keyPressedメソッドのif条件の中に貼り付けるだけです。以下は、期待通りに動作するコードです:

package edu.uno.ai.planning.bfs; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Gun extends JPanel implements KeyListener{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private static final int GUN_WIDTH = 100; 
    private static final int GUN_HEIGHT = 30; 
    private static final int GUN_UPPER_HEIGHT = 20; 
    private static final int GUN_UPPER_WIDTH = GUN_WIDTH/4; 
    int x, y; 
    int velX; 

    public Gun() { 
     x = 250 - GUN_WIDTH/2; 
     y = 500 - GUN_HEIGHT; 
     velX = 0; 
     addKeyListener(this); 

     setFocusable(true); 
     setFocusTraversalKeysEnabled(false); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 

     int upperX = x + GUN_WIDTH/2 - GUN_UPPER_WIDTH/2; 
     int upperY = y - GUN_UPPER_HEIGHT; 

     g2d.setColor(Color.BLACK); 
     g2d.fillRect(x, y, GUN_WIDTH, GUN_HEIGHT); 
     g2d.fillRect(upperX, upperY, GUN_UPPER_WIDTH, GUN_UPPER_HEIGHT); 
    } 

    public void left() { 
     velX = -1; 
    } 

    public void right() { 
     velX = 1; 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     // TODO Auto-generated method stub 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_LEFT) { 
      left(); 
      System.out.println("LEFT"); 
      x += velX; 
      repaint(); 
     } 
     if (key == KeyEvent.VK_RIGHT) { 
      right(); 
      System.out.println("RIGHT"); 
      x += velX; 
      repaint(); 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent arg0) { 
    } 

    @Override 
    public void keyTyped(KeyEvent arg0) { 
    } 

    public static void main(String[] args) { 
     Gun gun = new Gun(); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setTitle("Game"); 
     frame.setLayout(new FlowLayout()); 

     gun.setPreferredSize(new Dimension(500, 500)); 

     frame.add(gun); 
     frame.setVisible(true); 
     frame.pack(); 
    } 

} 
+0

ちょうどそれをしました!しかし、同じコードを数回使用するのは悪い習慣ではありませんか? – Mantas

+0

重複したコードが複数の行であったり、何回か使用しなければならない場合は、必ずメソッドを宣言してそのメソッドを呼び出すことをお勧めします。しかし、あなたのケースでは、複製されたコードは2行で、2箇所だけで使用しなければなりませんでした。したがって、私は個々の場所に行をコピーしました。しかし、いつも別のメソッドを宣言し、必要に応じてそのメソッドを呼び出すことができます。プログラミングは科学と芸術の組み合わせです。メソッドを宣言するか、アートセクションにするかは、やや主観的です。したがって、メソッドを使用するかコードを複製するかを決定するために、あなたの最高の本能を使用します。 –

関連する問題