使用键盘向下键在Jpanel上移动BALL [英] Move a BALL on Jpanel with keyboard down key

查看:96
本文介绍了使用键盘向下键在Jpanel上移动BALL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class mypanel extends from jpanel where i use the graphics and make a ball. Second class is Main where i make a JFrame and add panel to frame. There is another class MKeyListener in Main which extends from KeyAdapter class where i handel the keyboard event. I have made a object of Jpanel class in Main class and register the MkeyListener class with the jpanel class. now i want to move down the ball on jpanel with down keyboard key butt ball is not moving down with down key that is code of my programe.

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 是挑剔的,它注册的组件必须具有焦点并且在它将触发关键事件之前是可聚焦的。它也可以被任何其他可聚焦组件覆盖,这可能是好事和坏事。

KeyListener is is picky, the component it is registered to must have focus AND be focuable before it will trigger key events. It can also be overridden by any other focusable component, which can be a good and bad thing.

通常建议使用密钥绑定API,这样可以控制超过触发事件所需的焦点水平。它的配置和可重用性通常也更加灵活

It's generally recommended to use the key bindings API instead, which gives you control over the focus level required to trigger events. It's also generally far more flexible in it's configuration and re-usability

参见如何使用键绑定以获取更多详细信息

See How to Use Key Bindings for more details

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 通常是个坏主意,你失去对管理层的控制权,这意味着它们可以在任何您不知情或无法控制的地方进行修改。

As a general piece of advice, it's generally a bad idea to expose fields of you object as public or package-private, you lose control over there management, meaning that they could be modified from any where with out your knowledge or control.

更好地自我控制这些价值观的管理(内部或通过使用getters)或通过模型 - 控制器范例

Better to self contain the management of these values (either internally or through the use of getters) or via a model-controller paradigm

这篇关于使用键盘向下键在Jpanel上移动BALL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆