簡體   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