第一个问题:
FRAME 窗口添加了组件后,为什么不响应 KEYPressed 事件???第二个问题:
keyPress 与 keyRelease 事件一般成对触发,为什么在 调用了 JOptionPane.showMessageDialog() 方法后, keyReleased 事件不触发了??第三个问题:
怎么样模拟键盘事件,让程序返回桌面,不使用 Runtime.exec() 的方式,使用模拟键盘事件的方式。下面是我的测试代码:import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;public class  FrameTest extends JFrame implements ActionListener
{ public KeyAdapter kd = new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
JOptionPane.showMessageDialog(null,"使用了键盘!----------");
System.out.println("使用了键盘!----------");
}
public void keyReleased(KeyEvent e)
{
//JOptionPane.showMessageDialog(null,"释放了键盘!");
System.out.println("释放了键盘!----------"); }
}; public FrameTest()
{
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
JButton jb = new JButton("Click");
jb.addActionListener(this);
//cp.add(jb);
JTextField tf = new JTextField(10);
//cp.add(tf);
tf.addKeyListener(kd);
this.addKeyListener(kd);
this.setSize(300,180);
this.setTitle("FrameTest");
setDefaultCloseOperation(EXIT_ON_CLOSE);
show();
// 下面注释的代码,想模拟 'windows+D ' 事件,但没有成功
/*
KeyEvent ke = new KeyEvent(this,1100,new Date().getTime(),KeyEvent.VK_WINDOWS,KeyEvent.VK_D,'D');
this.kd.keyPressed(ke);
KeyEvent kup = new KeyEvent(this,1100,new Date().getTime(),KeyEvent.VK_WINDOWS,KeyEvent.VK_D,'D');
this.kd.keyReleased(kup);
*/ } public void actionPerformed(ActionEvent event)
{ } public static void main(String[] args) 
{
FrameTest ft = new FrameTest();
}
}

解决方案 »

  1.   

    增加了组件,比如你程序里的cp.add(jb),jb默认是获得了焦点的,你的键盘监听只是对JFrame,所以需要取消jb上的焦点,jb.setFocusable(false);
      

  2.   

    第一个问题: 
    frame处于最底下,当有东西放到他上面时,就会把他给覆盖掉了,从而使他frame得不到焦点,也就触发不了Key事件第二个问题
    JOptionPane.showMessageDialog是线程同步的,当弹出dialog时,焦点已转到dialog,父窗口已失去焦点,也就是说当按下键时随着dialog的弹出就已经失去了焦点,所以也就不存在键的释放第三个问题
    不太明白你所要问的意思?
      

  3.   

    第二个我估计是由于MessageDialog弹出太快了,马上获得了焦点,时候released的监听被阻断了,可以人工加一个线程,然后延迟MessageDialog弹出的时间,比如延迟0.1秒,让released有时间去监听到修改如下:public KeyAdapter kd = new KeyAdapter() {
    public void keyPressed(KeyEvent e) {
    new Thread(new Runnable() {
    @Override
    public void run() {
    try {
    Thread.sleep(100); // 这里模拟稍微等候一下,然监听可以到released
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    JOptionPane.showMessageDialog(null, "使用了键盘!----------"); }
    }).start();
    System.out.println("使用了键盘!----------");
    } public void keyReleased(KeyEvent e) {
    // JOptionPane.showMessageDialog(null,"释放了键盘!");
    System.out.println("释放了键盘!----------"); }
    };
      

  4.   

    第三个问题的意思:
    当窗口显示的时候,模拟WINDOWS 的键盘事件: windows+D ,就是返回桌面组合键。
    关于第一个问题:我还是比较认同 (whatisjava_open )的回答,毕竟通过设置setFocusable(false)的方法不是很可取,当窗口上组件比较多的时候,就不是很好的解决方案了。
      

  5.   

    第三个问题:
    如果你只是想实现 windows+D ,就返回桌面组合键  这样的功能的话,那你不用做什么,这样的功能是已经有的,因为这是windows的功能如果你是想实现一个全局键盘监听的话,那么可以这样做:
    把FrameTest再实现AWTEventListener这个接口,你会得到一个接口方法:
    public void eventDispatched(AWTEvent event) {
    }
    再构造子里面加这两行代码
    Toolkit toolkit = Toolkit.getDefaultToolkit(); 
    toolkit.addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);在eventDispatched方法里面:
    public void eventDispatched(AWTEvent event) {
            KeyEvent ke = (KeyEvent)event;        System.out.println("做你想做的 ...");
    }
      

  6.   

    win + d这个不用模拟吧,直接就返回桌面了啊?如果是鼠标点击一个什么按钮,触发win + d的键盘事件还能明白。
    jb.setFocusable(false)只是一个说法,就这个例子而言还可以用this.setFocusable(true);就可以了,让JFrame获得焦点。
      

  7.   

    那好,解决最主要的问题:通过按钮来触发win + d的键盘事件import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    import java.util.*;public class  FrameTest extends JFrame implements ActionListener
    { public KeyAdapter kd = new KeyAdapter(){
    public void keyPressed(KeyEvent e)
    {
    System.out.println("使用了键盘!----------");
    }
    public void keyReleased(KeyEvent e)
    {
    System.out.println("释放了键盘!----------"); }
    }; public FrameTest()
    {
    Container cp = getContentPane();
    cp.setLayout(new FlowLayout());
    JButton jb = new JButton("Click");
    jb.addActionListener(this);
    cp.add(jb);
    JTextField tf = new JTextField(10);
    cp.add(tf); this.setFocusable(true);
    tf.addKeyListener(kd);
    this.addKeyListener(kd);
    this.setSize(300,180);
    this.setTitle("FrameTest");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    show();


    KeyEvent ke = new KeyEvent(this,1100,new Date().getTime(),0,KeyEvent.VK_WINDOWS,(char)KeyEvent.VK_WINDOWS);
    this.kd.keyPressed(ke); ke = new KeyEvent(this,1100,new Date().getTime(),0,KeyEvent.VK_D,'D');
    this.kd.keyPressed(ke); } public void actionPerformed(ActionEvent event)
    {
    //JOptionPane.showMessageDialog(null,"按下了按钮!----------");
    KeyEvent ke = new KeyEvent(this,1100,new Date().getTime(),KeyEvent.VK_WINDOWS,KeyEvent.VK_D,'D');
    this.kd.keyPressed(ke);
    KeyEvent kup = new KeyEvent(this,1100,new Date().getTime(),KeyEvent.VK_WINDOWS,KeyEvent.VK_D,'D');
    this.kd.keyReleased(kup);
    } public static void main(String[] args) 
    {
    FrameTest ft = new FrameTest();
    }
    }
      

  8.   

    鼠标点击一个什么按钮,触发win + d的键盘事件 的问题,有人知道怎么解决吗?
      

  9.   

    你要实现win+D键的效果,给你个代码:import java.awt.Robot;
    import java.awt.event.KeyEvent;public class Test{
    public static void main(String args[])throws Exception{
    Robot r = new Robot();
    r.keyPress(KeyEvent.VK_WINDOWS);
    r.keyPress(KeyEvent.VK_D);
    //按下了要释放,要不然将会出现奇怪的问题~嘿嘿
    r.keyRelease(KeyEvent.VK_WINDOWS);
    r.keyRelease(KeyEvent.VK_D);

    }
    }你只要把代码放到合适的地方即可,这样写虽然能在windows下使用,但是其他系统就不行了