2015-08-24 22 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示例,以获取入门示例。