user3054008
user3054008

Reputation: 1

ActionListener and KeyListener not working at all

package Objects;

import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;



public class PowerBar extends JPanel implements ActionListener, KeyListener {

private double x;
private final double y = 420;
private double xv = 0;
private final int width, height;
private boolean left = false, right = false;
private Timer t = new Timer(5, this);

public PowerBar(JPanel j) {
    width = j.getWidth();
    height = j.getHeight();
    x = 180;

    t.start();
    this.addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);

  }

  public void move() {

  }

  public void powerbarPosition() {

  }

  @Override
  public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    Rectangle2D rect = new Rectangle2D.Double(x, y, 100, 15);
    g2.setColor(Color.DARK_GRAY);
    g2.fill(rect);
  }

  @Override
  public void actionPerformed(ActionEvent ae) {
    x += xv;
    repaint();
  }

  @Override
  public void keyPressed(KeyEvent ev) {
    if (ev.getKeyCode() == KeyEvent.VK_LEFT) {
        left = !left;
        if (left == true) {
            xv = -2;
        } else if (ev.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = !right;
            if (right == true) {
                xv = 2;
            }
        }
      }
    }

    @Override
    public void keyReleased(KeyEvent ev) {

    }

    @Override
    public void keyTyped(KeyEvent ke) {

    }

    }

Im kinda new to programming and this is my very first game to program. Im trying to get the power bar to move with the left and right key but there is no response from these keys when pressed. The power bar is drawn in a separate class called DrawMain which uses the paintComponent method.

Upvotes: 0

Views: 4942

Answers (2)

alex2410
alex2410

Reputation: 10994

1) Your ActionListener doesn't attached to JPanel and components on it, because of that it doesn't work.

2) Don't use KeyListener instead of use Key Bindings:

getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0), "doSomething1");
getActionMap().put("doSomething1", new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
         left = !left;
         if (left == true) {
             xv = -2;
         }
    }
});

getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "doSomething2");
getActionMap().put("doSomething2", new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
           right = !right;
            if (right == true) {
                xv = 2;
            }
    }
});

Upvotes: 3

Sage
Sage

Reputation: 15408

  1. A JPanel doesn't listen to Action, it is a container rather than a controller. Hence, it doesn't have a addActionListener(actionListener) function.
  2. For listening to Key event- presse, release etc, the target component must have focus. However, you can invoke requestFocusInWindow() on target component to gain focus if you wish to.
  3. It is preferable not to implement a listener to class which doesn't listen to such listener, in your context it is ActionListener. Make use of inline anonymous class or declare another class implementing the ActionListener
  4. As @AndrewThompson and other swing gigs of stackoverflow will suggest, It is preferable using Key binding using key input map and action input map to a component which is rather higher level implementation. Try avoiding make use of lower level AWT implementation KeyListener as much as possible.

Check the official tutorial page:

  1. How to use Key Bingings
  2. How to Write a Key Listener
  3. How to Write an Action Listener

Upvotes: 4

Related Questions