2013-02-18 49 views
4

干擾我有Java Swing應用程序ToolTipMouseTestJLabel的工具提示使用的MouseListener

的臨界線是label.setToolTipText("label" + i);。一旦它被註釋掉很點擊標籤在控制檯產生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"); 
    } 
} 
} 

回答

12

它如預期運行。讓我解釋一下爲什麼。

當您添加工具提示的任何組件(在你的情況標籤),他們會自動從ToolTipManager收到一個新的鼠標監聽器。下面是來自ToolTipManager類的註冊方法:

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

當任何一個組件都有ATLEAST一個鼠標監聽器設置就可以了 - 它會阻止任何鼠標進入/退出/點擊/按下/釋放事件(鼠標拖動/感動如果有鼠標移動偵聽器設置)從組件層次結構中下移。

在你的情況 - 標籤阻止從下降到因當提示設置安裝ToolTipManager聽衆分層窗格的鼠標事件和鼠標移動事件。如果你與一個解決辦法監聽器會通過事件下降

這可能是可以避免的。例如,您可以使用應該傳遞鼠標事件的工具提示將該偵聽器添加到每個組件。

下面是如何可以做一個小例子:

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

在這種情況下,事件將被傳遞到分層窗格雖然。無論如何,你甚至可以在任何你想要的地方派發這個(我想你的案例將會是spane)。

+0

+1有關詳細和完整的答案。 – 2014-07-25 11:59:07