Move the BALL on the Jpanel with the down key

I have a class mypanel extending from jpanel where I use graphics and make a ball. The second class is Main, where I create a JFrame and add the panel to the frame. There is another MKeyListener class in Main that extends from the KeyAdapter class, where I carry the keyboard event. I created an object of the Jpanel class in the main class and registered the MkeyListener class with the jpanel class. now i want to go down the ball on the jpanel with an empty keyboard ball that doesn’t move down with the down key which is my program code.

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");
  }
    }
}

}

      

+3


source to share


1 answer


KeyListener

is legible, the component it is registered to must have focus and be usable before it will fire key events. It can also be overridden by any other component that can be good or bad.

In general, it is recommended that you use the Key Binding API, which gives you control over the level of focus required to fire events. It also tends to be much more configurable and reusable in it

See How to use key bindings for 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);
        }
    }

}

      

As a general recommendation, it is usually a bad idea to expose the fields of your object as public

or package-private

, you lose control over this control, that is, they can be modified from anywhere without your knowledge or control.

It is better for yourself to contain management of these values ​​(internally or using getters) or using the model-controller paradigm

+3


source







All Articles