我有一个类mypanel从jpanel延伸,我使用图形并制作一个球。第二个类是Main,我在这里创建一个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");
}
}
}
}
答案 0 :(得分:3)
KeyListener
是挑剔的,它注册的组件必须具有焦点并且在它将触发关键事件之前是可聚焦的。它也可以被任何其他可聚焦组件覆盖,这可能是好事和坏事。
通常建议使用密钥绑定API,这样可以控制触发事件所需的焦点级别。它的配置和可重用性通常也更加灵活
有关详细信息,请参阅How to Use Key Bindings
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)或通过模型 - 控制器范例