Java KeyListener does not listen after regaining focus
I am using Eclipse to develop a java application using OpenJDK on Ubuntu 10.10
When using a keylistner with a Jframe, the Keylistner works perfect till the frame has focus, but if a switch focus to another application and then return the focus back to the Jframe, it does not start listening to keypresses this time. What I need to do is that the keylistener should again start working when the frame regains focus. there is only one frame in my application.
I have implemented a KeyListner, added it to a JFrame:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import code.NewJFrame;
public class Gamepad implements KeyListener
{
boolean button_up;
boolean button_down;
boolean button_right;
boolean button_left;
boolean b1;
boolean b2;
boolean b3;
boolean b4;
boolean select;
boolean start;
boolean r1;
boolean r2;
boolean l1;
boolean l2;
boolean joyl_up;
boolean joyl_down;
boolean joyl_right;
boolean joyl_left;
boolean joyr_up;
boolean joyr_down;
boolean joyr_right;
boolean joyr_left;
final static char BUTTON_UP ='Q' ;
final static char BUTTON_DOWN='W';
final static char BUTTON_RIGHT='E';
final static char BUTTON_LEFT='R';
final static char B1='T';
final static char B2='Y';
final static char B3='U';
final static char B4='I';
final static char SELECT='O';
final static char START='P';
final static char R1='A';
final static char R2='S';
final static char L1= 'D';
final static char L2= 'F';
final static char JOYL_UP='G';
final static char JOYL_DOWN='H';
final static char JOYL_RIGHT='J';
final static char JOYL_LEFT='K';
final static char JOYR_UP='L';
final static char JOYR_DOWN='Z';
final static char JOYR_RIGHT='X';
final static char JOYR_LEFT='C';
public Gamepad()
{
button_up = false;
button_down= false;
button_right= false;
button_left= false;
b1= false;
b2= false;
b3= false;
b4= false;
select= false;
start= false;
r1= false;
r2= false;
l1= false;
l2= false;
}
/**
* @param args
*/
public static void main(String[] args)
{
NewJFrame nj = new NewJFrame();
Gamepad gp = new Gamepad();
nj.addKeyListener(gp);
nj.setVisible(true);
}
@Override
public void keyPressed(KeyEvent e)
{
char c= Character.toUpperCase( e.getKeyChar() );
System.out.println("PRESSED:\t"+c);
if(c==BUTTON_UP) button_up=true;
else if(c==BUTTON_DOWN) button_down=true;
else if(c==BUTTON_RIGHT) button_right=true;
else if(c==BUTTON_LEFT) button_left=true;
else if(c==B1) b1=true;
else if(c==B2) b2=true;
else if(c==B3) b3=true;
else if(c==B4) b4=true;
else if(c==SELECT) select=true;
else if(c==START) { start=!start; Global.playToggle();}
else if(c==R1) r1=true;
else if(c==R2) r2=true;
else if(c==L1) l1=true;
else if(c==L2) l2 =true;
else if(c==JOYL_DOWN) joyl_down =true;
else if(c==JOYL_LEFT) joyl_left =true;
else if(c==JOYL_RIGHT) joyl_right =true;
else if(c==JOYL_UP) joyl_up =true;
else if(c==JOYR_DOWN) joyr_down =true;
else if(c==JOYR_LEFT) joyr_left =true;
else if(c==JOYR_RIGHT) joyr_right =true;
else if(c==JOYR_UP) joyr_up =true;
}
@Override
public void keyReleased(KeyEvent e)
{
char c= Character.toUpperCase( e.getKeyChar() );
System.out.println("RELEASED:\t"+e.getKeyChar());
if(c==BUTTON_UP) button_up=true;
else if(c==BUTTON_DOWN) button_down=false;
else if(c==BUTTON_RIGHT) button_right=false;
else if(c==BUTTON_LEFT) button_left=false;
else if(c==B1) 开发者_JS百科 b1=false;
else if(c==B2) b2=false;
else if(c==B3) b3=false;
else if(c==B4) b4=false;
else if(c==SELECT) select=false;
else if(c==START) ;//{start=false; Global.playToggle();}
else if(c==R1) r1=false;
else if(c==R2) r2=false;
else if(c==L1) l1=false;
else if(c==L2) l2 =false;
else if(c==JOYL_DOWN) joyl_down =false;
else if(c==JOYL_LEFT) joyl_left =false;
else if(c==JOYL_RIGHT) joyl_right =false;
else if(c==JOYL_UP) joyl_up =false;
else if(c==JOYR_DOWN) joyr_down =false;
else if(c==JOYR_LEFT) joyr_left =false;
else if(c==JOYR_RIGHT) joyr_right =false;
else if(c==JOYR_UP) joyr_up =false;
}
@Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub
}
}
I ran into keylistener/window focus issues myself, in Linux (gnome).
I did some tracing and discovered: 1) when you click off the window, the LOST FOCUS is NOT fired (no focus event is fired). 2) regaining focus/clicking on the window, causes it to fire the LOST FOCUS event, not the gain focus.
The fix that seems to be working for me right now:
frame.addFocusListener(new FocusListener(){
public void focusGained(FocusEvent e){
System.out.println("Focus GAINED:"+e);
}
public void focusLost(FocusEvent e){
System.out.println("Focus LOST:"+e);
// FIX FOR GNOME/XWIN FOCUS BUG
e.getComponent().requestFocus();
}
});
Basically requesting focus when focus is lost. Doesn't appear to break anything for windows users either, the icon might flash on your start bar when you lose focus, at the worse.
Also, if you want to do the debugging like I did, here is that code:
Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener(){
public void eventDispatched(AWTEvent e) {
System.out.println("AWT:"+e);
System.out.flush();
}
}, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK | WindowEvent.WINDOW_EVENT_MASK);
Hope this helps someone!
精彩评论