还是java键盘监听问题,测试程序中没问题,主程序中仍然不监听。

失落夏天
Android领域优质创作者
博客专家认证
2012-11-06 10:32:40
前面的大家不用怎么看,因为是完全自己写的,所以比较乱,麻烦大家稍微耐心一点帮忙看下。想实现最后的那个键盘监听的功能(按下↑按键时打印up),仍然不起作用。这是什么原因,应该如何解决?

package com.briup.main;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import com.briup.exit.ExitOrRestart;
import com.briup.help.Remain;
import com.briup.help.Saveing;
import com.briup.help.Score;
import com.briup.help.Timer;
import com.briup.help.Title;
import com.briup.login.LoginMain;
import com.briup.login.StartOrExit;
import com.briup.object.AddFighter;
import com.briup.object.ControlSubmarine;
import com.briup.object.Door;
import com.briup.object.Fighter;
import com.briup.object.Shoot;
import com.briup.object.Xianshi;

public class MyFrame extends JPanel{
//导入图像
final ImageIcon zhadan=new ImageIcon(MyFrame.class.getResource("/image/炸弹图.jpg"));
final ImageIcon feiji=new ImageIcon(MyFrame.class.getResource("/image/feiji.jpg"));
final ImageIcon controlsubmarine=new ImageIcon(MyFrame.class.getResource("/image/潜艇图.jpg"));

//游戏开始以前的时候的对象
private LoginMain loginMain;
private Door door;//控制门的对象door
private Title title;//控制艺术字标题的对象
private StartOrExit soe;//控制开始或者结束的对象

//临时标记位
private Map<Integer, Fighter> map;//记录飞机对象的map
private int n=0;//记录shoot线程的数量
private int num=20;//记录炮弹的剩余数量
private int i=700;//标记数据,记录潜艇的初始位置
private int j=400;
private static boolean flag=false;

//对象的创建
private JFrame frame;
private Shoot shoot;//炮弹的对象
private AddFighter addFighter;
private Fighter[] fighter;//轰炸机的对象组
private ControlSubmarine cs;//控制的潜艇的对象
private ExitOrRestart exitOrRestart;

//上侧显示页面的控件
private Xianshi xianshi;//这是背景显示的JPanel,里面包括背景,飞机,控制潜艇,炮弹等元素。

//下侧控制页面的控件
private JPanel panelkongzhi;
private PanelSelf panelself;
private PanelBisha panelbisha;
private PanelFangxiang panelfangxiang;
private PanelHuoli panelhuoli;
private PanelScores panelscores;

//自方信息界面的控件
private JPanel panelchijiu;
private JLabel textchijiu;
private JLabel chijiu;
private JPanel paneldanyao;
private JLabel textdanyao;
private JLabel danyao;//显示弹药的剩余数量的JLabel

//必杀技界面的控件
private JPanel panelsaveing;
private JLabel textsaveing;
private Saveing saveing;
private JPanel panelremain;
private JLabel textremain;
private Remain remain;
//方向界面的控件
private JButton shangBtn;
private JButton xiaBtn;
private JButton zuoBtn;
private JButton youBtn;
//火力控制界面的控件
private JPanel panelshoot;
private JPanel panelsuper;
private JButton shootBtn;
private JButton superBtn;
//得分界面的控件

private Score score;//得分界面
private JTextField textscore;
private JTextArea xinxi;

//退出界面的控件
private JButton restartBtn;
private JButton exitBtn;

//容器
private Container contentPane;

public MyFrame(){};
public MyFrame(String title){
frame=new JFrame();
frame.setSize(800,700);//xianshi宽800高600,状态栏高度为25,控制框高度为100
frame.setResizable(false);//页面大小不可更改

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
init();
}
private void init() {
contentPane.setLayout(null);

//对上侧的显示界面进行设置
xianshi=new Xianshi();
xianshi.setBounds(0, 0, 800, 600);
xianshi.setLayout(null);

//对下侧的控制页面进行设置
panelkongzhi = new JPanel();
panelkongzhi.setLayout(null);
panelkongzhi.setBounds(0, 600, 800, 100);

//创建血量弹药(自己的信息)界面
danyao=new JLabel();
chijiu=new JLabel();
panelself=new PanelSelf(panelchijiu, textchijiu, chijiu, paneldanyao, textdanyao, danyao, num);

//创建必杀技界面
saveing=new Saveing();
remain=new Remain(saveing);
panelbisha=new PanelBisha(panelsaveing,textsaveing,saveing,panelremain,textremain,remain);

//潜艇的初始位置
cs=new ControlSubmarine("飞翔号",panelself.getChijiu());
cs.setIcon(controlsubmarine);
cs.setBounds(i, j, 30, 10);

//创建方向控制界面
shangBtn=new JButton("上");//在方向控制界面创建 向上 按钮
xiaBtn=new JButton("下");
zuoBtn=new JButton("左");
youBtn=new JButton("右");
panelfangxiang=new PanelFangxiang(cs,shangBtn, xiaBtn, zuoBtn, youBtn);

//创建火力控制界面
shootBtn=new JButton("普通发射");
superBtn=new JButton("超级发射");
panelhuoli=new PanelHuoli(panelshoot, panelsuper, shootBtn, superBtn);

//创建得分界面
score=new Score();//添加分数类的对象
panelscores=new PanelScores(score, textscore, xinxi);


//游戏开始以前的时候界面进行设置
map=new HashMap<Integer, Fighter>();
addFighter=new AddFighter(xianshi, map,cs);
soe=new StartOrExit(panelfangxiang,addFighter);
title=new Title();

door=new Door(soe,title);
door.setVisible(false);
loginMain=new LoginMain(door);//功能是创建静态的登陆窗口,并且验证登陆功能

restartBtn=new JButton("重新开始");
exitBtn=new JButton("离开游戏");
exitOrRestart=new ExitOrRestart(cs,addFighter,restartBtn,exitBtn,panelfangxiang,panelbisha);
new Thread(exitOrRestart).start();

xianshi.add(exitOrRestart);
xianshi.add(title);
xianshi.add(soe);
xianshi.add(loginMain);
xianshi.add(door);

xianshi.add(cs);//添加潜艇
contentPane.add(xianshi);

panelkongzhi.add(panelself);//添加持久弹药界面
panelkongzhi.add(panelbisha);//添加必杀技界面
panelkongzhi.add(panelfangxiang);//添加控制方向界面
panelkongzhi.add(panelhuoli);//添加火力控制界面
panelkongzhi.add(panelscores);//添加得分界面
contentPane.add(panelkongzhi);
setAll();
}

public void setAll(){
//对火力控制界面的监听
final Timer time=new Timer();//时间控制对象,该对象每三秒把flag置为true,允许潜艇发射
new Thread(time).start();
shootBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(panelfangxiang.getFlag()){//判断是否已经点击开始

if(time.getFlag()){//判断时间间隔是否够三秒
if(num>0){
//初始化一个对象
shoot=new Shoot(n,map,score,saveing);//对进行炮弹的位置初始化
shoot.setSize(10,10);
shoot.setIcon(zhadan);//显示炸弹这张图片
shoot.setLocation(cs.getX()+10, cs.getY());//初始化炮弹的位置
xianshi.add(shoot);
//点击一次开火就创建一个新的线程
new Thread(shoot).start();
//记录线程的数量n
n++;
//计数器加1
num--;//剩余炮弹数减一
danyao.setText(Integer.toString(num));
time.setFlase();
}else{
System.out.println("剩余炮弹数量不足,请补充");
}
}else{
//少于三秒钟时不做反应
System.out.println("等待时间少于三秒,请稍后");
}
}
System.out.println("发射的炮弹数为:"+n);
}
});
restartBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("重新开始");//游戏进入正式开始的界面
//改变标记位,使飞机开始运行
addFighter.setFighter();
cs.setFlagTrue();//设置潜艇的标记让飞机可以运行
cs.setVisible(true);//让潜艇显示出来
exitOrRestart.setFalseLocation();//把退出页面放到显示框外面
exitOrRestart.setFlag();//标志位置为true,使exitOrRestart的run可以运行
cs.setChijiu();//把持久调整为30
cs.setTextChijiu();//使持久显示框刷新出来
num=20;//把炮弹数调整为20发
panelself.setDanyao();//使炮弹显示框刷新出来
//允许炮弹的发射
panelfangxiang.setFlag();
//分数清0,(应该恢复到这关开始之前的分数)
score.setScoreFor0();
new Thread(exitOrRestart).start();//再次启动一个线程,对持久进行监听,等到其再次为0
}
});
exitBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("离开游戏");
System.exit(0);
}
});
//问题就在这里,以下的监听代码都不执行,但是单独写的测试类的键盘监听是可以用的
panelfangxiang.addKeyListener(new KeyListener(){
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
System.out.println("测试是否成功");
if(keyCode==KeyEvent.VK_UP){
System.out.println("up");
}else if(keyCode==KeyEvent.VK_DOWN){
System.out.println("down");
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
});
panelfangxiang.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void focusLost(FocusEvent arg0) {
// TODO Auto-generated method stub
panelfangxiang.requestFocus();
}
});
panelfangxiang.requestFocus();

}

public void show(){
frame.setVisible(true);
}
}








...全文
211 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-11-20
  • 打赏
  • 举报
回复
楼主,你这个问题解决了?
dracularking 2012-11-16
  • 打赏
  • 举报
回复
引用 8 楼 yousun4688 的回复:
应该在面板被加入窗体之前加入监听事件
监听事件应该与监听对象紧密相关的,应该是独立的,为什么会与添加的顺序有关呢,按理应该是添加之后起就要生效才对。 object.addXyzListener(listener);
yousun4688 2012-11-16
  • 打赏
  • 举报
回复
引用 9 楼 dracularking 的回复:
引用 8 楼 yousun4688 的回复:应该在面板被加入窗体之前加入监听事件 监听事件应该与监听对象紧密相关的,应该是独立的,为什么会与添加的顺序有关呢,按理应该是添加之后起就要生效才对。 object.addXyzListener(listener);
不好意思我弄错了,你试试把键盘监听放在最外层的JFrame中吧,我以前好像也遇到过
dracularking 2012-11-15
  • 打赏
  • 举报
回复
单独可以的话,怕是受什么影响,一点点剥离其它code,直到能监听为止。
yousun4688 2012-11-15
  • 打赏
  • 举报
回复
应该在面板被加入窗体之前加入监听事件
lieyanfeng 2012-11-15
  • 打赏
  • 举报
回复
同4楼,你添加一个监听 frame(或者jpanel).addFocusListener(new FocusListener(){ @Override public void focusGained(FocusEvent arg0) { // TODO Auto-generated method stub } @Override public void focusLost(FocusEvent arg0) { // TODO Auto-generated method stub panelkongzhi.requestFocus(); } }); 添加到最下面
失落夏天 2012-11-15
  • 打赏
  • 举报
回复
抱歉因为忙, 好久没弄,谁帮下忙?
失落夏天 2012-11-06
  • 打赏
  • 举报
回复
下午4点左右的时候再来坐等高手们帮忙解答
失落夏天 2012-11-06
  • 打赏
  • 举报
回复
引用 1 楼 diggywang 的回复:
main方法呢? 建议MyFrame显示后,再调用MyFrame.getPanelFangxiang.requestFocus
main方法写在了一个测试类中了。。 就是一个new Myframe(); 另外MyFrame显示正常,其它的一切都挺正常的,就是键盘监听不管用 这只是一部分代码,也是主体,很多功能都写在了其它类当中了。
diggywang 2012-11-06
  • 打赏
  • 举报
回复
main方法呢? 建议MyFrame显示后,再调用MyFrame.getPanelFangxiang.requestFocus
diggywang 2012-11-06
  • 打赏
  • 举报
回复
变通一下嘛,panelfangxiang.requestFocus();要放在mainframe的show代码最后 你之前的代码中,主界面还没有显示出来,怎么可能获取到焦点,当然不会响应键盘事件!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧