繁体   English   中英

JLabel ToolTip会干扰MouseListener

[英]JLabel ToolTip interferes with MouseListener

我有Java Swing应用程序ToolTipMouseTest

关键行是label.setToolTipText("label" + i); 一旦注释掉,点击一个标签2 mousePressed在控制台中产生2 mousePressed 启用此行后,单击标签将不会产生任何效果。

这是预期的行为还是一个错误? 我的目标是显示工具提示而不禁用MouseListener

几乎是SSCCE,但没有进口:

public class ToolTipMouseTest {

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new ToolTipMouseTest();
        }
    });
}

public ToolTipMouseTest() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());

    JLayeredPane lpane = new JLayeredPane() {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600,400);
        }
    };

    MouseAdapter1 mouseAdapter1 = new MouseAdapter1();
    lpane.addMouseListener(mouseAdapter1);

    frame.add(lpane);

    JPanel panel1 = new JPanel();
    panel1.setSize(new Dimension(600, 400));
    panel1.setOpaque(false);

    lpane.add(panel1, JLayeredPane.PALETTE_LAYER);

    JPanel panel2 = new JPanel();
    for (int i = 0; i < 5; i++) {
        JLabel label = new JLabel("Label " + i);
        panel2.add(label);
        label.setToolTipText("label" + i); //HERE!!
    }

    JScrollPane spane = new JScrollPane(panel2) {
        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 200);
        }
    };

    MouseAdapter2 mouseAdapter2 = new MouseAdapter2();
    spane.addMouseListener(mouseAdapter2);

    panel1.add(spane);

    frame.pack();
    frame.setVisible(true);
}

private class MouseAdapter1 extends MouseAdapter {
    @Override
    public void mousePressed (MouseEvent me) {
        System.out.println("1 mousePressed");
    }
}

private class MouseAdapter2 extends MouseAdapter {
    @Override
    public void mousePressed (MouseEvent me) {
        System.out.println("2 mousePressed");
    }
}
}

它按预期工作。 让我解释一下原因。

当您向任何组件(案例中的标签)添加工具提示时,它们会自动从ToolTipManager接收新的鼠标侦听器。 这是ToolTipManager类的register方法:

public void registerComponent(JComponent component) {
    component.removeMouseListener(this);
    component.addMouseListener(this);
    component.removeMouseMotionListener(moveBeforeEnterListener);
    component.addMouseMotionListener(moveBeforeEnterListener);
    component.removeKeyListener(accessibilityKeyListener);
    component.addKeyListener(accessibilityKeyListener);
}

当任何组件上至少有一个鼠标监听器设置时 - 它将阻止任何鼠标进入/退出/单击/按下/释放事件(鼠标移动监听器设置时拖动/移动鼠标)从组件层次结构中向下移动。

在您的情况下 - 由于在设置工具提示时安装了ToolTipManager侦听器,标签会阻止鼠标事件和鼠标移动事件下降到分层窗格。

如果您使用会将事件向下传递的变通方式侦听器,则可以避免这种情况。 例如,您可以使用应该传递鼠标事件的工具提示将该侦听器添加到每个组件。

这是一个如何做到的小例子:

label.addMouseListener ( new MouseAdapter ()
{
    public void mousePressed ( MouseEvent e )
    {
        lpane.dispatchEvent ( SwingUtilities.convertMouseEvent ( e.getComponent (), e, lpane ) );
    }
} );

在这种情况下,事件将传递到分层窗格。 无论如何,你甚至可以在任何你想要的地方发送这个(我想在你的情况下它会是spane )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM