Java-Key Bindings无法正常工作/ actionPerformed未被调用

时间:2015-05-26 01:06:54

标签: java swing graphics user-input key-bindings

我终于学会了如何让图形在java中工作,这要归功于那个帮我解决上一个问题的人,但现在我无法获得关键的绑定工作。我知道我需要它来调用图形方法,我认为我已经正确地声明了我的键绑定,但是' actionPerformed()'方法不会打电话。我尝试使用单例模式在各个类中获取我的播放器对象,我觉得它以某种方式搞砸了其他所有内容。我试着查看与我的问题有关的其他一些问题,但我仍然无法弄清楚,除非我忽略了一些明显的问题。如果你们其中一位雄伟的编程向导能破解这一点,我真的很感激:

import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.KeyStroke;

public class Player {
    private int xLoc, yLoc;
    private boolean isFiring;
    private String filename;
    private ImageIcon imageicon;
    private URL imgURL;

    private static Player player;

    public Player(int xl, int yl, boolean fire, String name){
        xLoc = xl;
        yLoc = yl;
        isFiring = fire;
        filename = name;
        imgURL = getClass().getResource(name);
        imageicon = new ImageIcon(imgURL);
    }

    public static Player getInstance(){
        if(player == null){
            player = new Player(0,0,false,"Dog.jpg");
        }
        return player;
    }

    public void fire(){

    }

    public int getX(){
        return xLoc;
    }
    public int getY(){
        return yLoc;
    }
    public void newX(int x){
        xLoc = x;
    }
    public ImageIcon getImg() {
        return imageicon;
    }
    public void newImg(ImageIcon ii){
        imageicon = ii;
    }
    public URL getURL(){
        return imgURL;
    }
    public void newURL(String n){
        imgURL = getClass().getResource(n);
    }
    public void updateObject(){
        imageicon = new ImageIcon(imgURL);
    }
}

import java.awt.Graphics;
import java.net.URL;

import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class GamePanel extends JPanel{
    int nameSwap = 0;
    Player player;
    public GamePanel(){
        player = Player.getInstance();
        repaint();
        System.out.println("Repaint method called");

        this.getInputMap().put(KeyStroke.getKeyStroke("A"), "moveLeft");
        this.getActionMap().put("moveLeft", new MoveLR(-1));

        this.getInputMap().put(KeyStroke.getKeyStroke("D"), "moveRight");
        this.getActionMap().put("moveRight", new MoveLR(1));

        this.getInputMap().put(KeyStroke.getKeyStroke("S"), "fire");
        this.getActionMap().put("fire", new Fire());
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(player.getImg().getImage(), player.getX(), player.getY(), 50, 50, null);
        //System.out.println("Graphics method called");
    }
}

import java.awt.Color;

import javax.swing.JFrame;

public class Window {

    public Window() {
        JFrame frame = new JFrame("Epic Game");
        frame.setSize(800,600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GamePanel panel = new GamePanel();
        frame.add(panel);

        frame.setVisible(true);

        while(true){
            panel.repaint();
        }
    }

    public static void main(String[] args){
        Window window = new Window();
    }
}   

import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;

import javax.swing.Action;

public class MoveLR implements Action{
    private int moveVal;
    Player player;
    public MoveLR(int mv){
        moveVal = mv;
        player = Player.getInstance();
        System.out.println("New MoveLR object made");
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        player.newX(player.getX() + 1);
        System.out.println("actionPerformed() called");
    }

    @Override
    public void addPropertyChangeListener(PropertyChangeListener arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public Object getValue(String arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void putValue(String arg0, Object arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setEnabled(boolean arg0) {
        // TODO Auto-generated method stub

    }
}

1 个答案:

答案 0 :(得分:4)

您使用的是错误的InputMap。使用getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)。这样,当JPanel没有焦点但显示在窗口中时,您将绑定到活动的键。默认的InputMap是用于JComponent.WHEN_FOCUSED的输入,只有在绑定的组件具有焦点时才有效,这不是您想要做或使用的。

this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), 
        "moveLeft");

还使用扩展AbstractAction的类,而不是实现Action的类,因为您的Actions未完全连线。是的,你可以在actionPerformed结束时重新绘制,只要你有一个对JPanel的引用,ActionEvent可以为你提供。

测试程序:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Window {

   public Window() {
      JFrame frame = new JFrame("Epic Game");
      frame.setSize(800, 600);
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      GamePanel panel = new GamePanel();
      frame.add(panel);

      frame.setVisible(true);

      // !! while (true) {
      // panel.repaint();
      // }
   }

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

@SuppressWarnings("serial")
class GamePanel extends JPanel {
   int nameSwap = 0;
   Player player;

   public GamePanel() {
      player = Player.getInstance();
      repaint();
      System.out.println("Repaint method called");

      this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "moveLeft");
      this.getActionMap().put("moveLeft", new MoveLR(-1));

      this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "moveRight");
      this.getActionMap().put("moveRight", new MoveLR(1));

      this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "fire");
      this.getActionMap().put("fire", new Fire());
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(player.getImg().getImage(), player.getX(), player.getY(), 50,
            50, null);
      // System.out.println("Graphics method called");
   }
}

class Player {
   private int xLoc, yLoc;
   private boolean isFiring;
   private String filename;
   private ImageIcon imageicon;
   // !! private URL imgURL;

   private static Player player;

   public Player(int xl, int yl, boolean fire, String name) {
      BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(Color.red);
      g2.fillOval(2, 2, 16, 16);
      g2.dispose();
      imageicon = new ImageIcon(img);
      xLoc = xl;
      yLoc = yl;
      isFiring = fire;
      filename = name;
      // !! imgURL = getClass().getResource(name);
      // imageicon = new ImageIcon(imgURL);
   }

   public static Player getInstance() {
      if (player == null) {
         player = new Player(0, 0, false, "Dog.jpg");
      }
      return player;
   }

   public void fire() {

   }

   public int getX() {
      return xLoc;
   }

   public int getY() {
      return yLoc;
   }

   public void newX(int x) {
      xLoc = x;
   }

   public ImageIcon getImg() {
      return imageicon;
   }

   public void newImg(ImageIcon ii) {
      imageicon = ii;
   }

   // !! public URL getURL(){
   // return imgURL;
   // }
   // !! public void newURL(String n){
   // imgURL = getClass().getResource(n);
   // }
   public void updateObject() {
      // !! imageicon = new ImageIcon(imgURL);
      System.out.println("update object called");
   }
}

class MoveLR extends AbstractAction {
   private int moveVal;
   Player player;

   public MoveLR(int mv) {
      moveVal = mv;
      player = Player.getInstance();
      System.out.println("New MoveLR object made");
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      // TODO Auto-generated method stub
      player.newX(player.getX() + moveVal);
      ((JPanel) e.getSource()).repaint();
      System.out.println("actionPerformed() called");
   }

}

class Fire extends AbstractAction {
   public Fire() {
      System.out.println("Fire created");
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
      System.out.println("Fire called");
   }
}