2015-08-24 37 views
-1

我正在製作鼠標事件偵聽器和處理程序。我有這樣的事情:讓JLabel定位在鼠標下?

JLabel status = new JLabel("I can change"); 

而且用我的MouseListener,我改變的JLabel的文字,根據給定的條件。我可以很容易地保持此JLabel在一個地方,例如在窗口的底部,像這樣:

add(status, BorderLayout.SOUTH); 

但我想要做的是採取的JLabel,並直接顯示它在鼠標下。這將是類似於

.setToolTipText 

方法,但我不能使用,因爲我在一個JDialog,這是在網格佈局格式內的圖像移動鼠標。請解釋如何將變化的JLabel直接保存在鼠標下,就像.setToolTipText一樣。

有內網格佈局兩個圖像,這是一個JDialog:

JDialog giraffewindow = new JDialog(); 
      Icon giraffe = new ImageIcon(getClass().getResource("giraffe.png")); 
      Icon windows = new ImageIcon(getClass().getResource("windows.png")); 

      giraffewindow.setLayout(new GridLayout(1, 2, 0, 0)); 
      giraffewindow.add(new JLabel (windows)); 
      giraffewindow.add(new JLabel (giraffe)); 

謝謝你這麼多,你正在閱讀這篇文章的時候,我真的很感謝你的投入幫助老鄉的努力程序員!

回答

1

爲此,您需要將JLabel的父容器(JDialog)的佈局設置爲絕對佈局。這將讓您手動設置標籤的位置。

佈局設置爲空:

myPanel.setLayout(null); 

然後,設置標籤的位置,調用setBounds方法:

status.setBounds(int xPos, int yPos, int width, int height); 

在你的情況,你會冒險xPosyPos到鼠標移動時的鼠標座標。如果您需要一些偏移量,您可能還想爲常數添加一些常數。

例如:

giraffewindow.add(status); 

    giraffewindow.addMouseMotionListener(new MouseMotionListener() { 

     @Override 
     public void mouseMoved(MouseEvent evt) { 
      status.setBounds(evt.getX(), evt.getY(), labelWidth, 
        labelHeight); 
     } 

     @Override 
     public void mouseDragged(MouseEvent arg0) {} 
    }); 

編輯:

我剛剛得知,有可能仍設置在非絕對佈局的界限,如GridLayout。我只假定支持絕對佈局,但快速測試證明我的錯誤。但是,向GridLayout添加另一個組件似乎會讓事情變得更糟。我公司將提供另一個更新的時候我解決此


編輯2:

爲了有JLabel不會弄亂佈局,你有兩個選擇:

  1. 使用GlassPane 。把玻璃板想象成覆蓋它下面組件的玻璃板。通過將JLabel添加到玻璃窗格而不是JDialog,我們可以避免弄亂佈局。請看下圖:

    JPanel glass = ((JPanel) giraffewindow.getGlassPane()); 
    glass.setVisible(true); 
    glass.add(status); 
    
    glass.addMouseMotionListener(new MouseMotionListener() { 
    
        @Override 
        public void mouseMoved(MouseEvent evt) { 
         status.setBounds(evt.getX(), evt.getY(), labelWidth, 
           labelHeight); 
        } 
    
        @Override 
        public void mouseDragged(MouseEvent arg0) { 
        } 
    }); 
    

這種方法的問題是,它攔截所有的鼠標事件,這意味着Jbutton將與這種玻璃的下面也不會。一些可能的解決方法包括讓玻璃看看每一個鼠標事件,並決定是否應該將該事件傳遞給另一個組件。有關如何使用此概念,請參閱here for an example

  • 另一種可能性是用JLayeredPane秒。注意:我幾乎沒有JLayeredPane的經驗,所以在這裏和那裏可能會有一些小的不準確之處。基本上,JLayeredPane允許您將組件層疊在一起。出於您的目的,我會創建兩個圖層:一個包含新的JPanel,其中包含圖像的GridLayout,另一個包含status移動標籤。請看下圖:

    JLayeredPane layeredPane = new JLayeredPane(); 
    { 
        JPanel imagePanel = new JPanel(); 
        layeredPane.add(imagePanel); 
        layeredPane.setLayer(imagePanel, 0); 
        imagePanel.setLayout(new GridLayout(1, 2, 0, 0)); 
        { 
         imagePanel.add(new JLabel (windows)); 
         imagePanel.add(new JLabel (giraffe)); 
        } 
    
        layeredPane.add(status); 
        layeredPane.setLayer(status, 1); 
    } 
    giraffewindow.add(layeredPane); 
    
  • 不幸的遭遇同樣的問題。您可以圍繞JPanel中的狀態標籤,並將鼠標偵聽器添加到此面板中,但不會將鼠標操作傳遞給下面的任何按鈕。或者,您可以簡單地將鼠標偵聽器添加到主要的JDialog,這意味着詛咒捕獲鼠標事件的組件(如JButton)將停止status標籤的移動。

    +0

    如果我將它設置爲null,我還會有我的網格佈局嗎? –

    +0

    對不起,我錯過了這個問題。 JDialog的佈局是GridLayout嗎? –

    +0

    是的,在JDialog中的GridLayout中有兩個圖像 –

    1

    but I cannot use that - setToolTipText()

    爲什麼?

    I am moving the mouse over an image

    您正在將鼠標移到支持工具提示文本的JLabel上。

    如果你想用你只需要重寫getToolTipLocation(...)方法鼠標移動提示如下證明:

    import java.awt.*; 
    import java.awt.event.*; 
    import javax.swing.*; 
    import javax.swing.*; 
    import javax.swing.plaf.*; 
    import javax.swing.UIManager.*; 
    
    
    public class ToolTipPanel extends JPanel 
    { 
        public ToolTipPanel() 
        { 
         setPreferredSize(new Dimension(200, 200)); 
         setToolTipText(""); 
        } 
    
        public void paintComponent(Graphics g) 
        { 
         g.setColor(Color.red); 
         g.fillRect(0, 0, 100, 200); 
         g.setColor(Color.blue); 
         g.fillRect(100, 0, 100, 200); 
        } 
    
        @Override 
        public String getToolTipText(MouseEvent e) 
        { 
         if (e.getX() < 100) 
          return "red"; 
         else 
          return "blue"; 
        } 
    
        @Override 
        public Point getToolTipLocation(MouseEvent e) 
        { 
         Point p = e.getPoint(); 
         p.y += 15; 
    
         return p; 
        } 
    
        private static void createAndShowGUI() 
        { 
         JFrame frame = new JFrame("SSCCE"); 
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
         frame.add(new ToolTipPanel()); 
         frame.setLocationByPlatform(true); 
         frame.pack(); 
         frame.setVisible(true); 
        } 
    
        public static void main(String[] args) 
        { 
         EventQueue.invokeLater(new Runnable() 
         { 
          public void run() 
          { 
           createAndShowGUI(); 
          } 
         }); 
        } 
    } 
    

    另一種方法是使用一個JXLayer繪製文本你移動你的鼠標。查看How to Decorate Components with the JLayer Class的Swing教程中的Responding to Events示例,以獲取入門示例。