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
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.
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);
}
}
}
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.
Better to self contain the management of these values (either internally or through the use of getters) or via a model-controller paradigm