Java JFrame未响应keylistener
嗨,我正在尝试向JFrame添加一个KeyListener。我以前做过,效果很好。现在我复制代码,让它监听另一个JFrame,但现在由于某种原因它停止了工作。我不知道我做错了什么 编辑:在我按下屏幕内2个JPanel中的一个按钮之前,看起来一切都正常。就好像在那之后它失去了焦点。我怎样才能解决这个问题 这是新JFrame的构造函数,我在其中添加了KeyListener:Java JFrame未响应keylistener,java,swing,jframe,keylistener,setfocus,Java,Swing,Jframe,Keylistener,Setfocus,嗨,我正在尝试向JFrame添加一个KeyListener。我以前做过,效果很好。现在我复制代码,让它监听另一个JFrame,但现在由于某种原因它停止了工作。我不知道我做错了什么 编辑:在我按下屏幕内2个JPanel中的一个按钮之前,看起来一切都正常。就好像在那之后它失去了焦点。我怎样才能解决这个问题 这是新JFrame的构造函数,我在其中添加了KeyListener: public class QuizSoftwareView extends JFrame implements View{
public class QuizSoftwareView extends JFrame implements View{
private Observable $model;
private Controller $controller;
public EditQuestionsView $editQuestionsView;
public EditTeamsView $editTeamsView;
public AdministratorMenu $adminMenu;
private boolean $isPressed; /* To check if we already listened to a key press event */
/**
* Constructor to make a new quiz
*/
public QuizSoftwareView(Observable model, Controller controller) {
this.setTitle(QuizSoftwareModel.$language.getMessages().getString("title"));
$model = model;
if (controller == null)
$controller = new QuizSoftwareController(model);
else
$controller = controller;
$isPressed = false;
initComponents();
setFocusable(true);
/* Add a keylistener for every team */
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("TEST");
int teamSize; /* team size*/
teamSize = ((QuizSoftwareModel) getModel()).getQuiz().getModel().getTeams().size();
System.out.println(teamSize);
/* F1 is keycode 112, so % 111 gives 1 -> team 1, team 1 gets button F1, team 2 gets button F2 and so on... */
if((e.getKeyCode() % 111) <= teamSize /*&& !alreadyPressed((e.getKeyCode() % 111))*/) { /* If you pressed a number under the teamsize we listen to it, and that team hasn't pressed their button before */
/* Give a pop up message to the admin that a team has pushed their button */
//buttonPressed((e.getKeyCode() % 111));
System.out.println("TESTT");
((QuizSoftwareController)getController()).showScoreView((e.getKeyCode() % 111));
}
}
});
$isPressed = false;
}
}
公共类QuizSoftwareView扩展JFrame实现视图{
私有可观测$模型;
私人控制器$控制器;
公共编辑问题视图$EditQuestionsView;
公共EditTeamsView$EditTeamsView;
公共管理员菜单$adminMenu;
private boolean$isPressed;/*检查我们是否已收听按键事件*/
/**
*构造函数进行新的测验
*/
公共QuizSoftwareView(可观测模型、控制器){
this.setTitle(QuizSoftwareModel.language.getMessages().getString(“title”));
$model=model;
如果(控制器==null)
$controller=新的QuizSoftwareController(型号);
其他的
$controller=控制器;
$isPressed=false;
初始化组件();
设置聚焦(真);
/*为每个团队添加一个keylistener*/
addKeyListener(新的KeyAdapter(){
按下公共无效键(按键事件e){
系统输出打印(“测试”);
int teamSize;/*团队规模*/
teamSize=((QuizSoftwareModel)getModel()).GetQuit().getModel().getTeams().size();
系统输出打印项次(团队规模);
/*F1是键码112,所以%111给出1->team 1,team 1得到按钮F1,team 2得到按钮F2等等*/
如果((e.getKeyCode()%111)啊,是的,我现在明白了:)在这种情况下,需要使用应用程序范围内的操作,或者是应用程序范围内的键侦听器,因为当子组件有焦点时,键侦听器将无法在容器上工作……看到这个问题了吗
编辑:当然总是有一个快速而肮脏的修复:p
试试这个:
public class Test2 extends JFrame {
private boolean $isPressed; /*
* To check if we already listened to a key
* press event
*/
/**
* Constructor to make a new quiz
*/
public Test2() {
this.setTitle("");
$isPressed = false;
setFocusable(true);
getContentPane().setLayout(new BorderLayout());
JButton b = new JButton();
b.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
@Override
public void focusGained(FocusEvent e) {
Test2.this.requestFocus();
}
});
getContentPane().add(b);
/* Add a keylistener for every team */
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("TEST");
}
});
$isPressed = false;
b.grabFocus();
pack();
}
/**
* @param args
*/
public static void main(String[] args) {
new Test2().setVisible(true);
}
}
所以本质上你可以在你的组件中添加一个焦点监听器。但是对于这个特殊的攻击,你需要为你的所有子组件添加一个焦点监听器。显然,你只需要定义一个FocusListener
,你可以在任何地方重用它,但是通常一个组件有焦点是有原因的,所以你不想只做i不要失去注意力,但也许对你来说,这并不重要
因此,请澄清一下,没有上面JButton上的FocusListener
“TEST”在控制台中打印,直到我单击按钮,然后它不再工作。然后使用FocusListener
,它将始终工作,因为当按钮具有焦点时,JFrame
将重新获得焦点,因此它上的keystener
将再次工作
解决此问题的另一种方法是定义KeyAdapter
的一个实例,并将其设置为该窗口中所有组件的keylister
。我意识到此线程有点旧,但我在尝试在全局级别捕获击键时不断遇到它。我终于找到了一种很好的方法我想我会在这里为其他人(和我自己)发帖,因为我相信两天后我会忘记的
我知道键绑定是首选方法,但有时你不应该用斧头将蚊子从额头上除掉。-在这里效果很好,假设你让JFrame可见,“测试”当我键入键时出现在控制台中。您尝试了第一个JFrame,对吗?嗯,让我再次检查一下。它现在可以工作了,我们在另一个类中使用了setVisible函数,我们现在将它放入构造函数中,现在可以工作了。Thanks@Shikamu它仍然不起作用,请检查问题中的编辑。是否有快速修复方法可以重新关注父JFrame?或者这不起作用吗?谢谢你的帮助;D,但问题是测验的管理员应该能够提出一个新问题->焦点转到提出新问题的JFrame,但是团队在这段时间内应该仍然能够按下按钮(监听器在父JFrame内),你明白我的意思吗?我喜欢你的脏补丁,但这仍然不能真正解决这个问题。有没有办法让父JFrame仍然能够响应被按下的键?或者我应该让添加问题JFrame成为这个JFrame中的一个JPanel来解决这个问题?因为这是模型视图控制器,有没有一个选项可以让我abFocus在更新中的JFrame中?这也可以解决问题。:)因此,在父JFrame中的JFrame中键入JTextField,仍然可以像F1一样响应按键并在父JFrame中处理它们?使用JPanel并将组件放入其中恐怕无法解决问题。如果您对c感兴趣对于特定的关键点,我建议研究一下我在答案中链接的问题。
public class Test2 extends JFrame {
private boolean $isPressed; /*
* To check if we already listened to a key
* press event
*/
/**
* Constructor to make a new quiz
*/
public Test2() {
this.setTitle("");
$isPressed = false;
setFocusable(true);
getContentPane().setLayout(new BorderLayout());
JButton b = new JButton();
b.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
@Override
public void focusGained(FocusEvent e) {
Test2.this.requestFocus();
}
});
getContentPane().add(b);
/* Add a keylistener for every team */
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
System.out.println("TEST");
}
});
$isPressed = false;
b.grabFocus();
pack();
}
/**
* @param args
*/
public static void main(String[] args) {
new Test2().setVisible(true);
}
}
KeyboardFocusManager kbfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
kbfm.addKeyEventDispather( new KeyEventDispatcher(){
public boolean dispatchKeyEvent(KeyEvent e){
if(e.getID() == KeyEvent.KeyPressed) {
switch(e.getKeyCode()) {
case KeyEvent.VK_A:
//Stuff to do when A is pressed
System.out.println("You pressed the 'A' key");
case KeyEvent.VK_B:
//Stuff to do when B is pressed
System.out.println("You pressed the 'B' key");
// add other cases as needed for other keys
}
}
//Allow event to be redispatched
return false;
}
} );