JPanel如何实现键盘监听

时间:2023-02-20 09:25:48
[align=center]我是看了马士兵的坦克大战后,想自己编写一个,我比较常用的GUI是swing
而且,我是在JPanel里画坦克的,但是我想在JPanel里添加一个键盘监听器,用来控制坦克的移动,但是添加后没有用
然后我试了在JPanel里添加一个JTextFeild,然后对它添加键盘监听,是可以的,这是为什么
如何实现直接对JPanel的键盘监听[/align]

13 个解决方案

#1


对JPanel实现键盘事件:addKeyListener
每一个小坦克可以是用一个图形来表示,在Panel上绘制出来,而非一个组件。
所以在键盘事件中,判断你选中的坦克是哪一个,然后计算移动后这个坦克图形的坐标,重新绘制。

#2


引用 1 楼 inhibitory 的回复:
对JPanel实现键盘事件:addKeyListener
每一个小坦克可以是用一个图形来表示,在Panel上绘制出来,而非一个组件。
所以在键盘事件中,判断你选中的坦克是哪一个,然后计算移动后这个坦克图形的坐标,重新绘制。

恩,视频上是用AWT里的组件画的,但是我自己写的不想跟他的一模一样,所以我用的是swing里的组件,我的坦克是在JPanel里画的,但是我把addKeyListener写进去后,并没有实现应该有的功能

#3


这个你要设置getFoused(),我记得好像是要设置成FALSE,方法名我也记得不是很清楚了,你必须把也JFrame的设置成FALSE,对你的Tank添加KeyListeneer,不需要去判断的!

#4


引用 3 楼 zhuyouyong 的回复:
这个你要设置getFoused(),我记得好像是要设置成FALSE,方法名我也记得不是很清楚了,你必须把也JFrame的设置成FALSE,对你的Tank添加KeyListeneer,不需要去判断的!

API里没有找到你所说的方法,你的意思是不是让JPanel获得焦点?
这个方法我也试过了,requestFocus(),这个是让该组件强制获得焦点,设置了,也还是不能实现键盘监听

#5


反正总有个容器获得焦点了嘛,比如你的Panel是放在Frame里边的,
就给Frame配个Listerner嘛

#6



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;



public class TankMain
{
public static void main(String[] args)
{
TankMainFrame f = new TankMainFrame();
//设置正常关闭
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置Frame可见
f.setVisible(true);
}
}

class TankMainFrame extends JFrame
{
public TankMainFrame()
{
//设置标题
setTitle("MyTank");
//设置出现的位置以及大小
setBounds(200, 100, 800, 600);
//设置大小不可变
setResizable(false);

TankMainPanel p = new TankMainPanel();
add(p);
}
}

class TankMainPanel extends JPanel
{
private int x = 50,y = 50;

public TankMainPanel()
{
//设置背景色
setBackground(Color.BLACK);
//让Panel获得焦点
requestFocus();
//给Panel添加键盘监听器(未实现)
addKeyListener(new KeyCommand());

//建立一个线程,让坦克动起来
new Thread(new TankRun()).start();
}
//重写画图的方法,用来画出所有的东西
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//取得原来的颜色
Color c = g.getColor();
//改成自己想用的颜色
g.setColor(Color.RED);
//画出一个圆,表示一个坦克
g.fillOval(x, y, 30, 30);
//设置回原来的颜色
g.setColor(c);
}

//写一个内部类,用来启动线程
private class TankRun implements Runnable
{
public void run()
{
try
{
//建立一个死循环
while(true)
{
//刷新界面
repaint();
//让线程休息50毫秒
Thread.sleep(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
//键盘监听类,实现用键盘控制坦克的移动
private class KeyCommand extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
//测试代码
System.out.println("OK");
//取得键值
// int key = e.getKeyCode();
//控制向右移
// if(key == KeyEvent.VK_RIGHT)
// {
// x+=5;
// }
}
}
}


这是我的代码,我给Panel添加了焦点,但是还是没用,我也试了给Frame加,也没有,请牛人帮我看看应该怎么改,可以实现键盘监听

#7


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;



public class TankMain
{
public static void main(String[] args)
{
TankMainFrame f = new TankMainFrame();
//设置正常关闭
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置Frame可见
f.setVisible(true);
}
}

class TankMainFrame extends JFrame
{
public TankMainFrame()
{
//设置标题
setTitle("MyTank");
//设置出现的位置以及大小
setBounds(200, 100, 800, 600);
//设置大小不可变
setResizable(false);

TankMainPanel p = new TankMainPanel();
add(p);
}
}

class TankMainPanel extends JPanel
{
private int x = 50,y = 50;

public TankMainPanel()
{
//设置背景色
setBackground(Color.BLACK);
//让Panel获得焦点
requestFocus();
//给Panel添加键盘监听器(未实现)
addKeyListener(new KeyCommand());

//建立一个线程,让坦克动起来
new Thread(new TankRun()).start();
}
//重写画图的方法,用来画出所有的东西
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//取得原来的颜色
Color c = g.getColor();
//改成自己想用的颜色
g.setColor(Color.RED);
//画出一个圆,表示一个坦克
g.fillOval(x, y, 30, 30);
//设置回原来的颜色
g.setColor(c);
}

//写一个内部类,用来启动线程
private class TankRun implements Runnable
{
public void run()
{
try
{
//建立一个死循环
while(true)
{
//刷新界面
repaint();
//让线程休息50毫秒
Thread.sleep(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
//键盘监听类,实现用键盘控制坦克的移动
private class KeyCommand extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
//测试代码
System.out.println("OK");
//取得键值
// int key = e.getKeyCode();
//控制向右移
// if(key == KeyEvent.VK_RIGHT)
// {
// x+=5;
// }
}
}
}

刚贴的不好,现在重贴一次

#8


直接JPanel.addKeyListener(),就OK拉!其余的事情自己搞定就好啦 !

#9


引用 8 楼 my_caterpillar 的回复:
直接JPanel.addKeyListener(),就OK拉!其余的事情自己搞定就好啦 !

但是现在的问题是,我加了等于没加啊,我贴的代码里有,可是运行后,监听功能就是实现不了,哪出问题了呢?怎么改

#10


最简单的方法,在frame里addKeyListener(x)当然 x 应该是单独的类或者frame的内部类,总之要对frame可见,而panel只管画图其他不管。

你把tank的坐标放在 panel里了,暂时只有坐标还可以,要是tank的属性多了就不如单独封装在一个类里了。

如果就是要在panel里边控制,
你可以试试在 panel 里加个方法:
public void processParentEvent(AWTEvent e){
    this.processEvent(e);
}
在frame里加:
addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e) {
        p.processParentEvent(e);
    }
});
这样frame所有的Event就交给panel来处理了

#11


引用 10 楼 avina2009 的回复:
 在frame里加:
 addKeyListener(new KeyAdapter(){
     public void keyPressed(KeyEvent e) {
         p.processParentEvent(e);
     }
 });
 这样frame所有的Event就交给panel来处理了

哦对,还要把 p 声明称 frame的成员变量

#12


引用 10 楼 avina2009 的回复:
最简单的方法,在frame里addKeyListener(x)当然 x 应该是单独的类或者frame的内部类,总之要对frame可见,而panel只管画图其他不管。

你把tank的坐标放在 panel里了,暂时只有坐标还可以,要是tank的属性多了就不如单独封装在一个类里了。

如果就是要在panel里边控制,
你可以试试在 panel 里加个方法:
public void processParentEvent(AWTEvent e){
    this.processEvent(e);
}
在frame里加:
addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e) {
        p.processParentEvent(e);
    }
});
这样frame所有的Event就交给panel来处理了

终于实现了,谢谢

#13


why it does not work in my application ? 

#1


对JPanel实现键盘事件:addKeyListener
每一个小坦克可以是用一个图形来表示,在Panel上绘制出来,而非一个组件。
所以在键盘事件中,判断你选中的坦克是哪一个,然后计算移动后这个坦克图形的坐标,重新绘制。

#2


引用 1 楼 inhibitory 的回复:
对JPanel实现键盘事件:addKeyListener
每一个小坦克可以是用一个图形来表示,在Panel上绘制出来,而非一个组件。
所以在键盘事件中,判断你选中的坦克是哪一个,然后计算移动后这个坦克图形的坐标,重新绘制。

恩,视频上是用AWT里的组件画的,但是我自己写的不想跟他的一模一样,所以我用的是swing里的组件,我的坦克是在JPanel里画的,但是我把addKeyListener写进去后,并没有实现应该有的功能

#3


这个你要设置getFoused(),我记得好像是要设置成FALSE,方法名我也记得不是很清楚了,你必须把也JFrame的设置成FALSE,对你的Tank添加KeyListeneer,不需要去判断的!

#4


引用 3 楼 zhuyouyong 的回复:
这个你要设置getFoused(),我记得好像是要设置成FALSE,方法名我也记得不是很清楚了,你必须把也JFrame的设置成FALSE,对你的Tank添加KeyListeneer,不需要去判断的!

API里没有找到你所说的方法,你的意思是不是让JPanel获得焦点?
这个方法我也试过了,requestFocus(),这个是让该组件强制获得焦点,设置了,也还是不能实现键盘监听

#5


反正总有个容器获得焦点了嘛,比如你的Panel是放在Frame里边的,
就给Frame配个Listerner嘛

#6



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;



public class TankMain
{
public static void main(String[] args)
{
TankMainFrame f = new TankMainFrame();
//设置正常关闭
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置Frame可见
f.setVisible(true);
}
}

class TankMainFrame extends JFrame
{
public TankMainFrame()
{
//设置标题
setTitle("MyTank");
//设置出现的位置以及大小
setBounds(200, 100, 800, 600);
//设置大小不可变
setResizable(false);

TankMainPanel p = new TankMainPanel();
add(p);
}
}

class TankMainPanel extends JPanel
{
private int x = 50,y = 50;

public TankMainPanel()
{
//设置背景色
setBackground(Color.BLACK);
//让Panel获得焦点
requestFocus();
//给Panel添加键盘监听器(未实现)
addKeyListener(new KeyCommand());

//建立一个线程,让坦克动起来
new Thread(new TankRun()).start();
}
//重写画图的方法,用来画出所有的东西
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//取得原来的颜色
Color c = g.getColor();
//改成自己想用的颜色
g.setColor(Color.RED);
//画出一个圆,表示一个坦克
g.fillOval(x, y, 30, 30);
//设置回原来的颜色
g.setColor(c);
}

//写一个内部类,用来启动线程
private class TankRun implements Runnable
{
public void run()
{
try
{
//建立一个死循环
while(true)
{
//刷新界面
repaint();
//让线程休息50毫秒
Thread.sleep(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
//键盘监听类,实现用键盘控制坦克的移动
private class KeyCommand extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
//测试代码
System.out.println("OK");
//取得键值
// int key = e.getKeyCode();
//控制向右移
// if(key == KeyEvent.VK_RIGHT)
// {
// x+=5;
// }
}
}
}


这是我的代码,我给Panel添加了焦点,但是还是没用,我也试了给Frame加,也没有,请牛人帮我看看应该怎么改,可以实现键盘监听

#7


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;



public class TankMain
{
public static void main(String[] args)
{
TankMainFrame f = new TankMainFrame();
//设置正常关闭
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置Frame可见
f.setVisible(true);
}
}

class TankMainFrame extends JFrame
{
public TankMainFrame()
{
//设置标题
setTitle("MyTank");
//设置出现的位置以及大小
setBounds(200, 100, 800, 600);
//设置大小不可变
setResizable(false);

TankMainPanel p = new TankMainPanel();
add(p);
}
}

class TankMainPanel extends JPanel
{
private int x = 50,y = 50;

public TankMainPanel()
{
//设置背景色
setBackground(Color.BLACK);
//让Panel获得焦点
requestFocus();
//给Panel添加键盘监听器(未实现)
addKeyListener(new KeyCommand());

//建立一个线程,让坦克动起来
new Thread(new TankRun()).start();
}
//重写画图的方法,用来画出所有的东西
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//取得原来的颜色
Color c = g.getColor();
//改成自己想用的颜色
g.setColor(Color.RED);
//画出一个圆,表示一个坦克
g.fillOval(x, y, 30, 30);
//设置回原来的颜色
g.setColor(c);
}

//写一个内部类,用来启动线程
private class TankRun implements Runnable
{
public void run()
{
try
{
//建立一个死循环
while(true)
{
//刷新界面
repaint();
//让线程休息50毫秒
Thread.sleep(50);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
//键盘监听类,实现用键盘控制坦克的移动
private class KeyCommand extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
//测试代码
System.out.println("OK");
//取得键值
// int key = e.getKeyCode();
//控制向右移
// if(key == KeyEvent.VK_RIGHT)
// {
// x+=5;
// }
}
}
}

刚贴的不好,现在重贴一次

#8


直接JPanel.addKeyListener(),就OK拉!其余的事情自己搞定就好啦 !

#9


引用 8 楼 my_caterpillar 的回复:
直接JPanel.addKeyListener(),就OK拉!其余的事情自己搞定就好啦 !

但是现在的问题是,我加了等于没加啊,我贴的代码里有,可是运行后,监听功能就是实现不了,哪出问题了呢?怎么改

#10


最简单的方法,在frame里addKeyListener(x)当然 x 应该是单独的类或者frame的内部类,总之要对frame可见,而panel只管画图其他不管。

你把tank的坐标放在 panel里了,暂时只有坐标还可以,要是tank的属性多了就不如单独封装在一个类里了。

如果就是要在panel里边控制,
你可以试试在 panel 里加个方法:
public void processParentEvent(AWTEvent e){
    this.processEvent(e);
}
在frame里加:
addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e) {
        p.processParentEvent(e);
    }
});
这样frame所有的Event就交给panel来处理了

#11


引用 10 楼 avina2009 的回复:
 在frame里加:
 addKeyListener(new KeyAdapter(){
     public void keyPressed(KeyEvent e) {
         p.processParentEvent(e);
     }
 });
 这样frame所有的Event就交给panel来处理了

哦对,还要把 p 声明称 frame的成员变量

#12


引用 10 楼 avina2009 的回复:
最简单的方法,在frame里addKeyListener(x)当然 x 应该是单独的类或者frame的内部类,总之要对frame可见,而panel只管画图其他不管。

你把tank的坐标放在 panel里了,暂时只有坐标还可以,要是tank的属性多了就不如单独封装在一个类里了。

如果就是要在panel里边控制,
你可以试试在 panel 里加个方法:
public void processParentEvent(AWTEvent e){
    this.processEvent(e);
}
在frame里加:
addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e) {
        p.processParentEvent(e);
    }
});
这样frame所有的Event就交给panel来处理了

终于实现了,谢谢

#13


why it does not work in my application ?