我有JPanel
使用BorderLayout
,其中包含2个组件。 JLabel
中的NORTH
和JList
中的CENTER
。
我在面板中添加了MouseListener
,暂时将消息框编码为mouseEntered
。
问题是只有当光标进入标签占用的区域时才会触发事件。当鼠标进入整个面板区域时,我需要触发事件。
知道我做错了什么吗?
编辑:创建面板的代码
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(new JLabel("Label"), BorderLayout.NORTH);
p.add(new JList(), BorderLayout.CENTER);
p.addMouseListener(new MouseListener(){
@Override
public void mouseEntered(MouseEvent e) {
JOptionPane.showMessageDialog(null, "Entered Panel");
}
//Other overriden methods
...
});
答案 0 :(得分:4)
从jdk7开始,您可以使用JLayer装饰任何JComponent并注册该层以接收分派给其子级的所有事件,例如
JTable list = new JTable(30, 5);
JComponent panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
panel.add(new JLabel("we are label"));
panel.add(new JScrollPane(list));
LayerUI<JComponent> ui = new LayerUI<JComponent>() {
@Override
protected void processMouseEvent(MouseEvent e, JLayer<? extends JComponent> l) {
if (e.getID() == MouseEvent.MOUSE_ENTERED) {
System.out.println(e.getSource().getClass() + " at " + e.getPoint());
}
}
};
JLayer<JComponent> layer = new JLayer<JComponent>(panel, ui);
layer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK );
请注意,这是由AWTEventListener内部处理的,就像Rob的博客中提出的解决方案一样。 Rob的解决方案的优势在于它也可以在沙盒上下文中工作(因为核心类JLayer具有必要的特权)。
对于早期的jdk版本,有一个project JXLayer(SwingLabs的一部分),它是新核心类的直接前身。它没有权限问题,因为它在内部使用稍微不同的方法来获取所有事件。
答案 1 :(得分:2)
我认为问题在于JList是接收鼠标事件的组件。我不确定这是解决问题的最佳方法,但是你不能将相同的鼠标监听器添加到JList中吗?
答案 2 :(得分:0)
任何具有MouseListener的组件都将收到鼠标事件,并且不会传递给面板。
您可以将MouseListener添加到每个组件,但如果面板的设计发生更改会怎样。不要忘记你可能在JList的右侧有一个滚动条,所以如果用户从右边进入面板,则只有鼠标在滚动条上移动到列表上才会生成事件。
相反,您可能需要考虑使用Global Event Listener来监听mouseEntered事件。然后,当收到事件时,您需要检查事件的来源是面板本身还是面板的子组件。你应该可以使用:
SwingUtiltities.isDescendingFrom(...)
帮助进行此项检查。