Java- 键绑定不工作/未调用 actionPerformed
Java- Key Bindings not working / actionPerformed not being called
感谢在上一个问题中帮助我的人,我终于学会了如何在 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
}
}
您使用了错误的 InputMap。使用getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
。这样,您将绑定到当 JPanel 没有焦点但显示在 window 中时处于活动状态的键。默认的 InputMap 是用于 JComponent.WHEN_FOCUSED
的那个,只有当绑定的组件有焦点时才有效,这不是你想要做的或使用的。
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"),
"moveLeft");
还使用扩展 AbstractAction 的 类,而不是实现 Action 的那些,因为您的 Actions 没有完全连接。是的,只要您有对 JPanel 的引用,您就可以在 actionPerformed 结束时重新绘制,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");
}
}
感谢在上一个问题中帮助我的人,我终于学会了如何在 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
}
}
您使用了错误的 InputMap。使用getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
。这样,您将绑定到当 JPanel 没有焦点但显示在 window 中时处于活动状态的键。默认的 InputMap 是用于 JComponent.WHEN_FOCUSED
的那个,只有当绑定的组件有焦点时才有效,这不是你想要做的或使用的。
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"),
"moveLeft");
还使用扩展 AbstractAction 的 类,而不是实现 Action 的那些,因为您的 Actions 没有完全连接。是的,只要您有对 JPanel 的引用,您就可以在 actionPerformed 结束时重新绘制,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");
}
}