有一个JFrame,添加了一个KeyListener,然后在JFrame上添加了JPanel,KeyListener失效,即JFrame接收不到KeyEvent
有一种解决办法,在JPanel上添加KeyListener,把KeyEvent post掉.   有没有更好的办法,因为用上面的办法很不优雅.   AWT/Swing里,好像子组件区域覆盖了父容器,那么父容器的监听器是接收不到事件通知的.

解决方案 »

  1.   

    查了下Toolkit,这个问题就解决了
      

  2.   


    比如弹出的对话框,按ESC关闭对话框,
    注意对话框里有JPanel,JTextArea,这样直接在JDialog上添加监听器是收不到KeyEvent的
      

  3.   


     我的意思是子组件挡住了父容器,导致父容器无法收到KeyEvent
    很简单的JPanel p = new JPanel(new BorderLayout());
    JTextArea t = new JTextArea();
    p.add(t);
    p.addKeyListener(new KeyAdapter(){
         public void keyPressed(KeyEvent){
              // 这里是不会执行的,因为JPanel收不到KeyEvent
         }
    });
      

  4.   

    KeyListener是否能监听到事件,
    不是看什么组件有没有覆盖住父组件
    而是看当前的焦点是在哪个组件上所以,如果你有这样的需求
    可以:
    一、始终让你添加了KeyListener的那个组件强制获得焦点
    二、给你经常会获得焦点的组件都添加KeyListener
      

  5.   

    JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
      

  6.   


    强制获得焦点,JTextArea不用输入了?
      

  7.   

    再描述下,就是父容器要接收到子组件上发生的感兴趣的事件怎么把组件上的事件,也传递到父容器呢?JDialog.add(new JTextArea())  这时JDialog是收不到KeyEvent的
      

  8.   


    父容器要接收到子组件上发生的感兴趣的事件
    怎么把组件上的事件,也传递到父容器呢?那自然是给子组件添加Listener,在Listener中处理,将事件传递给父组件但是如果这样做,何不把父组件要处理的的动作,直接放到子组件的Listener中去呢?
    反正子组件加一个Listener是免不了的因为直接产生KeyEvent,就是当前焦点的组件不过我对Swing的了解程度不够深,
    说不定也有直接让非焦点组件产生KeyEvent的方法
    不过有研究出这个的时间,你把Listener写在子组件中,代码可能早就写好了
      

  9.   

    没焦点,那还不简单。
    给JPanel加个requestFocus方法
      

  10.   


    如果有n个子组件呢,就得在所有子组件上addKeyListener其实AWT1.1以前的事件机制就是,往上冒泡型的,子组件不处理就交给父组件处理,直到根.
    1.1以后,就采用观察者模式了.
    我现在就是要用往上冒泡型的,可以在Listener里调用getParent().dispatchEvent(AWTEvent),
    把事件传递给父组件.
    如果有n个子组件,这样做也很麻烦.最好的方式应该是:
       JDialog.addXXXListener(new XXXListener(){
             public void xxx(AWTEvent e){
                  //  这里能收到所有在自己或者孩子上发生的事件
                 //  然后对感兴趣的做出处理
             }
       });挻多人来讨论的,1楼我就说解决了
    sun给出的方式是:
         Toolkit.addAWTListener() // 方法名好像是这么写