Java - JPanel上的MouseListener没有触发

时间:2011-12-13 14:50:32

标签: java swing event-handling jpanel mouselistener

我有JPanel使用BorderLayout,其中包含2个组件。 JLabel中的NORTHJList中的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
        ...
    });

3 个答案:

答案 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(...)

帮助进行此项检查。