ActionListener not working

when I press 'A' I don't do anything. I am making a game and I do not see any wrong writing of the code.

And if you have any sugestion on what to put in 2D simple survival game, please advise.

I am not getting any errors.

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 java.awt.geom.Ellipse2D;

import javax.swing.*;


public class Player extends JPanel implements ActionListener{
Timer time = new Timer(5, this);
double x = 0; double velX = 2;
double y = 0; double velY = 2;

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    Ellipse2D circle = new Ellipse2D.Double(x,y,40,40);
    g2.fill(circle);
    time.start();
}

public void keyPressed(KeyEvent e){
    int key = e.getKeyCode();
    if(key == KeyEvent.VK_A){
        System.out.println("VK_A"); // When i press 'A' don't print this
        velX = 1;
        x = 1;
        x += velX;
        x += 1;
        //velY = 0;
    }
}



public void actionPerformed(ActionEvent e){
    //x += velX;
    //y += velY;
    //x = x + velX;
    //y = y + velY;
    repaint();
  }
}

      

+3


source to share


2 answers


You don't have JButtons and are being called addActionListener(...)

to nothing, so it makes sense that this won't work. Solution: add a JButton and add an ActionListener to this button. Also, your question states that the ActionListener doesn't work, but your comment appears to be inside a non-existent KeyListener. This suggests that you really want to check out the Swing tutorials. You can find links to Swing tutorials and other Swing resources: Swing Info .

Other comments:

1) Re

I am not getting any errors.

The lack of compilation errors does not mean there are no logical errors (as you will find out).

2) Never start a timer from the paintComponent method. This method should only be for drawing and painting.



3) A

Use key bindings to respond to the press . The tutorials linked above will show you how to use them.

For example:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.*;

// public class Player extends JPanel implements ActionListener {
public class Player extends JPanel { // !! avoid having GUI implement listener interfaces
   private static final int TIME_DELAY = 15; // avoid magic numbers
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   Timer time = new Timer(TIME_DELAY, new TimerListener());
   double x = 0;
   double velX = 2;
   double y = 0;
   double velY = 2;

   public Player() {
      // start timer here!
      time.start();

      setKeyBindings();
   }

   private void setKeyBindings() {
      // get action and input maps
      int condition = WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      // get keystroke
      KeyStroke aKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);

      // bind keystroke with an action
      inputMap.put(aKeyStroke, aKeyStroke.toString());
      actionMap.put(aKeyStroke.toString(), new A_Action());
   }

   @Override
   //!! public void paintComponent(Graphics g) {
   protected void paintComponent(Graphics g) {  // should be protected not public
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      Ellipse2D circle = new Ellipse2D.Double(x, y, 40, 40);
      g2.fill(circle);
   }

   @Override //!! make bigger
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class A_Action extends AbstractAction {
      @Override
      public void actionPerformed(ActionEvent e) {
         System.out.println("A key pressed");
         x++;
         y++;
         repaint();
      }
   }

   public void actionPerformed(ActionEvent e) {
      // x += velX;
      // y += velY;
      // x = x + velX;
      // y = y + velY;
      repaint();
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         // TODO: move x and y
         repaint();
      }
   }

   private static void createAndShowGui() {
      Player mainPanel = new Player();

      JFrame frame = new JFrame("Player");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

      


Here is a more complete example that does all the movement in the Timer ActionListener. It uses an enumeration called "Direction" as well as a map that associates four direction enumeration values ​​with a boolean. Key bindings will change the Boolean value on the Map, and that's all. For example, if the up arrow is clicked, then the Map Boolean logic associated with Direction.UP will be correct. When the key has been released, the map value associated with the same Direction.UP key will be changed to false. The ActionListener timer will loop through the four direction enums, checking the map value for each enumeration, and then move the sprite in the direction indicated by the directive if the associated boolean is true. Benefits include the ability to respond to multiple keystrokes simultaneously:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class MoveCircle extends JPanel { 
   private static final int TIME_DELAY = 15; // avoid magic numbers
   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   Timer time = new Timer(TIME_DELAY, new TimerListener());

   // key presses and releases will change the boolean values held in this Map
   // When an arrow key is pressed, the direction-corresponding boolean is set true
   // and likewise when the arrow key is released the direction corresponding boolean is false
   private Map<Direction, Boolean> dirMap = new EnumMap<>(Direction.class);
   private double x = 0;
   private double velX = 2;
   private double y = 0;
   private double velY = 2;

   public MoveCircle() {
      setKeyBindings();
      time.start();      
   }

   private void setKeyBindings() {
      int condition = WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      // iterate through all the Direction enums
      for (Direction direction : Direction.values()) {
         // set all values to false
         dirMap.put(direction, false);

         // create two key strokes, one for pressed and one for released
         int keyValue = direction.getKeyValue();
         KeyStroke pressedKey = KeyStroke.getKeyStroke(keyValue, 0, false);
         KeyStroke releasedKey = KeyStroke.getKeyStroke(keyValue, 0, true);

         // create two Actions, one for pressed, one for released
         Action pressedAction = new KeyAction(direction, true);
         Action releasedAction = new KeyAction(direction, false);

         // add keystroke to inputMap and use keystroke toString as binding link
         inputMap.put(pressedKey, pressedKey.toString());
         inputMap.put(releasedKey, releasedKey.toString());

         // link binding links to our actions
         actionMap.put(pressedKey.toString(), pressedAction);
         actionMap.put(releasedKey.toString(), releasedAction);
      }
   }

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

      // draw smooth circles
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      Ellipse2D circle = new Ellipse2D.Double(x, y, 40, 40);
      g2.fill(circle);
   }

   @Override 
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class KeyAction extends AbstractAction {
      private Direction direction;
      private boolean pressed;

      public KeyAction(Direction direction, boolean pressed) {
         this.direction = direction;
         this.pressed = pressed;               
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         dirMap.put(direction, pressed); // key press simply changes the map, that it.
      }
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         // if JPanel no longer displayed, stop the Timer
         if (!MoveCircle.this.isDisplayable()) {
            ((Timer) e.getSource()).stop();
         }
         // here the key: iterate through the Direction enum
         for (Direction direction : Direction.values()) {
            // get corresponding boolean from dirMap
            // and if true, change location of x and y
            if (dirMap.get(direction)) {
               x += velX * direction.getDeltaX();
               y += velY * direction.getDeltaY();
            }
         }
         repaint();
      }
   }

   private static void createAndShowGui() {
      MoveCircle mainPanel = new MoveCircle();

      JFrame frame = new JFrame("Move Circle");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

enum Direction {
   UP("Up", KeyEvent.VK_UP, 0, -1),
   DOWN("Down", KeyEvent.VK_DOWN, 0, 1),
   LEFT("Left", KeyEvent.VK_LEFT, -1, 0),
   RIGHT("Right", KeyEvent.VK_RIGHT, 1, 0);

   private String text; 
   private int keyValue; // KeyEvent.VK_?
   private int deltaX; 
   private int deltaY;

   Direction(String text, int keyValue, int deltaX, int deltaY) {
      this.text = text;
      this.keyValue = keyValue;
      this.deltaX = deltaX;
      this.deltaY = deltaY;
   }

   public String getText() {
      return text;
   }

   public int getKeyValue() {
      return keyValue;
   }

   @Override
   public String toString() {
      return text;
   }

   public int getDeltaX() {
      return deltaX;
   }

   public int getDeltaY() {
      return deltaY;
   }

}

      

+4


source


public class Player extends JPanel implements ActionListener, KeyListener{

      



You must also implement a keylistener to listen for key presses. ActionListener handles button clicks.

0


source







All Articles