有一个JFrame,添加了一个KeyListener,然后在JFrame上添加了JPanel,KeyListener失效,即JFrame接收不到KeyEvent
有一种解决办法,在JPanel上添加KeyListener,把KeyEvent post掉.
有没有更好的办法,因为用上面的办法很不优雅.
AWT/Swing里,好像子组件区域覆盖了父容器,那么父容器的监听器是接收不到事件通知的.
15 个解决方案
#1
查了下Toolkit,这个问题就解决了
#2
添加全局监听么啊你要实现什么?
#3
比如弹出的对话框,按ESC关闭对话框,
注意对话框里有JPanel,JTextArea,这样直接在JDialog上添加监听器是收不到KeyEvent的
#4
想象一下··你的意思就是你的一个容器里包含两个控件,然后两个控件分别有监听··是这样吗?方便的话贴一下代码啊··
#5
我的意思是子组件挡住了父容器,导致父容器无法收到KeyEvent
很简单的
JPanel p = new JPanel(new BorderLayout());
JTextArea t = new JTextArea();
p.add(t);
p.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent){
// 这里是不会执行的,因为JPanel收不到KeyEvent
}
});
#6
不可以直接给窗体添加键盘监听么??
#7
KeyListener是否能监听到事件,
不是看什么组件有没有覆盖住父组件
而是看当前的 焦点是在哪个组件上
所以,如果你有这样的需求
可以:
一、始终让你添加了KeyListener的那个组件强制获得焦点
二、给你经常会获得焦点的组件都添加KeyListener
不是看什么组件有没有覆盖住父组件
而是看当前的 焦点是在哪个组件上
所以,如果你有这样的需求
可以:
一、始终让你添加了KeyListener的那个组件强制获得焦点
二、给你经常会获得焦点的组件都添加KeyListener
#8
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
#9
强制获得焦点,JTextArea不用输入了?
#10
再描述下,就是父容器要接收到子组件上发生的感兴趣的事件
怎么把组件上的事件,也传递到父容器呢?
JDialog.add(new JTextArea()) 这时JDialog是收不到KeyEvent的
怎么把组件上的事件,也传递到父容器呢?
JDialog.add(new JTextArea()) 这时JDialog是收不到KeyEvent的
#11
父容器要接收到子组件上发生的感兴趣的事件
怎么把组件上的事件,也传递到父容器呢?
那自然是给子组件添加Listener,在Listener中处理,将事件传递给父组件
但是如果这样做,何不把父组件要处理的的动作,直接放到子组件的Listener中去呢?
反正子组件加一个Listener是免不了的
因为直接产生KeyEvent,就是当前焦点的组件
不过我对Swing的了解程度不够深,
说不定也有直接让非焦点组件产生KeyEvent的方法
不过有研究出这个的时间,你把Listener写在子组件中,代码可能早就写好了
#12
没焦点,那还不简单。
给JPanel加个requestFocus方法
给JPanel加个requestFocus方法
#13
#14
#15
如果有n个子组件呢,就得在所有子组件上addKeyListener
其实AWT1.1以前的事件机制就是,往上冒泡型的,子组件不处理就交给父组件处理,直到根.
1.1以后,就采用观察者模式了.
我现在就是要用往上冒泡型的,可以在Listener里调用getParent().dispatchEvent(AWTEvent),
把事件传递给父组件.
如果有n个子组件,这样做也很麻烦.
最好的方式应该是:
JDialog.addXXXListener(new XXXListener(){
public void xxx(AWTEvent e){
// 这里能收到所有在自己或者孩子上发生的事件
// 然后对感兴趣的做出处理
}
});
挻多人来讨论的,1楼我就说解决了
sun给出的方式是:
Toolkit.addAWTListener() // 方法名好像是这么写
#1
查了下Toolkit,这个问题就解决了
#2
添加全局监听么啊你要实现什么?
#3
比如弹出的对话框,按ESC关闭对话框,
注意对话框里有JPanel,JTextArea,这样直接在JDialog上添加监听器是收不到KeyEvent的
#4
想象一下··你的意思就是你的一个容器里包含两个控件,然后两个控件分别有监听··是这样吗?方便的话贴一下代码啊··
#5
我的意思是子组件挡住了父容器,导致父容器无法收到KeyEvent
很简单的
JPanel p = new JPanel(new BorderLayout());
JTextArea t = new JTextArea();
p.add(t);
p.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent){
// 这里是不会执行的,因为JPanel收不到KeyEvent
}
});
#6
不可以直接给窗体添加键盘监听么??
#7
KeyListener是否能监听到事件,
不是看什么组件有没有覆盖住父组件
而是看当前的 焦点是在哪个组件上
所以,如果你有这样的需求
可以:
一、始终让你添加了KeyListener的那个组件强制获得焦点
二、给你经常会获得焦点的组件都添加KeyListener
不是看什么组件有没有覆盖住父组件
而是看当前的 焦点是在哪个组件上
所以,如果你有这样的需求
可以:
一、始终让你添加了KeyListener的那个组件强制获得焦点
二、给你经常会获得焦点的组件都添加KeyListener
#8
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
#9
强制获得焦点,JTextArea不用输入了?
#10
再描述下,就是父容器要接收到子组件上发生的感兴趣的事件
怎么把组件上的事件,也传递到父容器呢?
JDialog.add(new JTextArea()) 这时JDialog是收不到KeyEvent的
怎么把组件上的事件,也传递到父容器呢?
JDialog.add(new JTextArea()) 这时JDialog是收不到KeyEvent的
#11
父容器要接收到子组件上发生的感兴趣的事件
怎么把组件上的事件,也传递到父容器呢?
那自然是给子组件添加Listener,在Listener中处理,将事件传递给父组件
但是如果这样做,何不把父组件要处理的的动作,直接放到子组件的Listener中去呢?
反正子组件加一个Listener是免不了的
因为直接产生KeyEvent,就是当前焦点的组件
不过我对Swing的了解程度不够深,
说不定也有直接让非焦点组件产生KeyEvent的方法
不过有研究出这个的时间,你把Listener写在子组件中,代码可能早就写好了
#12
没焦点,那还不简单。
给JPanel加个requestFocus方法
给JPanel加个requestFocus方法
#13
#14
#15
如果有n个子组件呢,就得在所有子组件上addKeyListener
其实AWT1.1以前的事件机制就是,往上冒泡型的,子组件不处理就交给父组件处理,直到根.
1.1以后,就采用观察者模式了.
我现在就是要用往上冒泡型的,可以在Listener里调用getParent().dispatchEvent(AWTEvent),
把事件传递给父组件.
如果有n个子组件,这样做也很麻烦.
最好的方式应该是:
JDialog.addXXXListener(new XXXListener(){
public void xxx(AWTEvent e){
// 这里能收到所有在自己或者孩子上发生的事件
// 然后对感兴趣的做出处理
}
});
挻多人来讨论的,1楼我就说解决了
sun给出的方式是:
Toolkit.addAWTListener() // 方法名好像是这么写