在学Java游戏开发的基础。写了两个类,想要实现监听键盘输入,图形在JFrame上移动。但是不知道为什么总是不动请各位高人指导一下。。感谢各位!我在想是不是repaint或者ActionListener出了问题?这是主类:import javax.swing.JFrame;public class Frame extends JFrame{ public Frame(){
this.setSize(500,500);
this.add(new Board());
this.addKeyListener(new Board());
this.setVisible(true);
}
public static void main(String[] args) {
new Frame(); }}
这是第JPanel类:import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import javax.swing.JPanel;public class Board extends JPanel implements KeyListener{
int x, y,dx,dy;
public Board(){ this.addKeyListener(this);
}
public void paint(Graphics g){
super.paint(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(x+dx,y+dy,50,50);
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_LEFT){
dx--;
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
dx++;
}
if(e.getKeyCode()==KeyEvent.VK_UP){
dy--;
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
dy++;
}
repaint();
}
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){
}
}
this.setSize(500,500);
this.add(new Board());
this.addKeyListener(new Board());
this.setVisible(true);
}
public static void main(String[] args) {
new Frame(); }}
这是第JPanel类:import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import javax.swing.JPanel;public class Board extends JPanel implements KeyListener{
int x, y,dx,dy;
public Board(){ this.addKeyListener(this);
}
public void paint(Graphics g){
super.paint(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(x+dx,y+dy,50,50);
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_LEFT){
dx--;
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
dx++;
}
if(e.getKeyCode()==KeyEvent.VK_UP){
dy--;
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
dy++;
}
repaint();
}
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){
}
}
解决方案 »
- 小白刚学习java,很多不懂得,求详细解释
- 读取一个文件存进一个字符串里遇到的问题
- 关于JToolbar上各个按钮如何同时显示图标和文字的问题
- 文件读写操作,如何重定位到文件头
- 两题JAVA招聘的笔试题,请大家帮我看一下
- [200分] 急急!! 求java判断U盘存在,并读取里面的文件
- Java文本框中实现鼠标数字的滚动
- jtable中如果先选中了第一个单元格,然后再选中同一行的最后一个单元格,为什么会选中一行
- 关于servlet输出中文奇怪的问题,高手们帮忙阿~~急~~
- 请问,那里有install anywhere下载?
- 在panel添加滚动条,怎么加啊?用JScrollBar了,可是还是不会。
- 跪求几本书,希望大家帮帮忙!
this.setSize(500, 500);
this.add(new Board());
this.addKeyListener(new Board());
this.setVisible(true);
}改成这样就行了: public Frame() {
this.setSize(500, 500);
Board board=new Board();
this.add(board);
this.addKeyListener(board);
this.setVisible(true);
}
我把根源分析一下吧问题一:先看一下你的KeyListener是在哪实现,又在哪添加的?
仔细看看可以发现,
你的KeyListener在你的这个Board的类中实现,并添加在了这个JPanel上
咋一看,感觉不用让Frame监听KeyListener应该也能有反应才对啊
就是说在Frame的构造方法中没有
this.addKeyListener(new Board());
这句话,应该也有方法让Board实现重绘
那问题就是为什么这个Frame起来后,我们按键没有反应呢?
那就是焦点问题,JPanel是无法通过鼠标点击获得焦点的
在你的JFrame起来后,默认的焦点是在JFrame上的,
而你却怎么样都无法让Board获得焦点
所以其实只要加一句话,就可以让你的Board实现重绘
就是这样改:
public Frame() {
this.setSize(500, 500);
Board board = new Board();
this.add(board);
this.setVisible(true);
board.requestFocus();
}board.requestFocus();
在JFrame起来后,让你的Board强制获得焦点,才能监听上面的键盘事件问题二:如果焦点在JFrame上,如何也能实现重绘呢?
那就是1楼的改法了,而这样子你的这个程序的结构就显得不是那么好了
因为你的KeyListener在Board类中实现,你却是为了让JFrame来监听这个KeyListener
那为什么不把KeyListener移植到JFrame类中实现呢?
这样改:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import javax.swing.JFrame;public class Frame extends JFrame implements KeyListener { private Board board;
public Frame() {
this.setSize(500, 500);
board = new Board();
this.add(board);
this.addKeyListener(this);
this.setVisible(true);
} public static void main(String[] args) {
new Frame();
} public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
board.dx--;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
board.dx++;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
board.dy--;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
board.dy++;
}
repaint();
} public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {}}
而你的Board类只要简简单单的这样:
import java.awt.Color;
import java.awt.Graphics;import javax.swing.JPanel;public class Board extends JPanel { int x, y, dx, dy; public Board() {
super();
}
public void paint(Graphics g) {
super.paint(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(x + dx, y + dy, 50, 50);
}
}问题三:paint方法
既然使用了Swing组件
我们建议就不要重写paint了,最好重写paintComponent这个方法
因为Swing在这个方法中使用了双缓冲机制,在界面刷新的时候,减少“闪动”的感觉
这是Swing的优势,不用这个太可惜了
这样子:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(x + dx, y + dy, 50, 50);
}