Java 使用键盘向下键在Jpanel上移动球

Java 使用键盘向下键在Jpanel上移动球,java,swing,keylistener,Java,Swing,Keylistener,我有一个mypanel类,它是从jpanel扩展而来的,我在jpanel中使用图形并制作一个球。第二节课是我制作JFrame并将面板添加到框架的主要部分。Main中还有另一个类MKeyListener,它从我处理键盘事件的KeyAdapter类扩展而来。我在Main类中创建了一个Jpanel类的对象,并向Jpanel类注册了MkeyListener类。现在我想用键盘键向下移动jpanel上的球,但球不是用键盘键向下移动,这是我程序的代码 import java.awt.*; import jav

我有一个mypanel类,它是从jpanel扩展而来的,我在jpanel中使用图形并制作一个球。第二节课是我制作JFrame并将面板添加到框架的主要部分。Main中还有另一个类MKeyListener,它从我处理键盘事件的KeyAdapter类扩展而来。我在Main类中创建了一个Jpanel类的对象,并向Jpanel类注册了MkeyListener类。现在我想用键盘键向下移动jpanel上的球,但球不是用键盘键向下移动,这是我程序的代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class mypanel extends JPanel{
     int n=0;
     int m=0;
     int i=170;
     int j=340;
     int a=60;
     int b=20;
    public void paintComponent (Graphics g){
        super.paintComponent(g);
        Graphics2D g2= (Graphics2D)g;
        g2.setColor(Color.green);
        g2.fillOval(n,m,10,10);
    }
}

public class Main {
    JFrame frame;
    mypanel p;
    int x,y;
    public Main (){
    x=0;
    y=0;    
     frame=new JFrame();
    Container c = frame.getContentPane();
    c.setLayout(new BorderLayout());
    p = new mypanel();
    c.add(p,BorderLayout.CENTER);
    frame.setSize(400,400);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MKeyListener k=new MKeyListener();
    p.addKeyListener(k);

    }

    public static void main(String args []) {
        Main a= new Main();
    }


class MKeyListener extends KeyAdapter {

    public void keyPressed(KeyEvent event) {

  if (event.getKeyCode()==KeyEvent.VK_DOWN ) {
      x =x+4;
            y=y+4;
         p.n+=x;
         p.m+=y;
         p.repaint();
   System.out.println("success");
  }
    }
}

}

KeyListener
很挑剔,它注册到的组件必须具有焦点,并且在触发键事件之前必须是可聚焦的。它也可以被任何其他可聚焦组件覆盖,这可能是好事,也可能是坏事

通常建议改用键绑定API,它使您可以控制触发事件所需的焦点级别。它的配置和可重用性通常也要灵活得多

有关更多详细信息,请参阅

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String args[]) {
        Main a = new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new MyPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyPanel extends JPanel {

        private int n = 0;
        private int m = 0;
        private int i = 170;
        private int j = 340;
        private int a = 60;
        private int b = 20;

        public MyPanel() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Action.down");
            am.put("Action.down", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    n += 4;
                    m += 4;
                    repaint();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.green);
            g2.fillOval(n, m, 10, 10);
        }
    }

}
作为一般建议,将对象的字段公开为
public
package private
,通常是一个坏主意,您将失去对这些管理的控制,这意味着它们可以在您不知情或不受控制的情况下从任何位置进行修改


最好自行包含这些值的管理(内部或通过使用getter)或通过模型控制器范式

我认为快速Snail的意思是,在
KeyListener上使用键绑定
,有关更多详细信息,请参阅我是java初学者,我无法理解在向侦听器注册组件时如何聚焦我不确定我是否理解您的评论