Java 在鼠标下放置JLabel?
我正在制作一个鼠标事件侦听器和处理程序。我有这样的想法:Java 在鼠标下放置JLabel?,java,user-interface,mouse,Java,User Interface,Mouse,我正在制作一个鼠标事件侦听器和处理程序。我有这样的想法: JLabel status = new JLabel("I can change"); add(status, BorderLayout.SOUTH); 使用我的MouseListener,我正在根据给定的条件更改JLabel的文本。我可以轻松地将此JLabel放在一个位置,例如在窗口底部,如下所示: JLabel status = new JLabel("I can change"); add(status, BorderLayo
JLabel status = new JLabel("I can change");
add(status, BorderLayout.SOUTH);
使用我的MouseListener,我正在根据给定的条件更改JLabel的文本。我可以轻松地将此JLabel放在一个位置,例如在窗口底部,如下所示:
JLabel status = new JLabel("I can change");
add(status, BorderLayout.SOUTH);
但是我想做的是,获取JLabel,并将其直接显示在鼠标下。这将类似于
.setToolTipText
方法,但我不能使用它,因为我将鼠标移动到JDialog中的图像上,该图像是网格布局格式的。请解释如何将正在更改的JLabel直接放在鼠标下,就像.setToolTiptText一样
GridLayout中有两个图像,位于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));
非常感谢您花这么多时间阅读本文,我非常感谢您为帮助一位程序员同事所付出的努力 为此,需要将
JLabel
的父容器(JDialog)的布局设置为绝对布局。这将允许您手动设置标签的位置
要将布局设置为null,请执行以下操作:
myPanel.setLayout(null);
然后,要设置标签的位置,请调用setBounds
方法:
status.setBounds(int xPos, int yPos, int width, int height);
在您的情况下,每当移动鼠标时,您都会将xPos
和yPos
偶然移动到鼠标的坐标。如果需要一点偏移量,您可能还需要向坐标添加一些常量
例如:
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
。我以为只有绝对布局支持这一点,但快速测试证明了我的错误。然而,在网格布局中添加另一个组件似乎有点混乱。我将在解决此问题时提供另一个更新
编辑2:
为了使JLabel
不会弄乱布局,您有两个选项:
使用玻璃窗格
。将窗格玻璃视为覆盖其下方组件的一片玻璃。通过将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) {
}
});
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);
这种方法的问题在于它会截获所有鼠标事件,这意味着JButtons和类似的玻璃下面的东西不会被截获。一些可能的解决方法包括让玻璃查看每个鼠标事件,并决定是否应该将该事件传递给另一个组件。有关如何使用此概念的详细信息,请参见
另一种可能性是使用JLayeredPane
s。注意:我几乎没有使用JLayeredPane
s的经验,因此可能会有一些小的误差。基本上,JLayeredPane
允许您将组件分层。出于您的目的,我将创建两个层:一个层包含一个新的JPanel
,其中GridLayout
包含图像,另一个层包含status
移动标签。见下文:
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) {
}
});
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
)进行诅咒将阻止状态标签移动
但是我不能使用-setToolTipText()
为什么?
我正在将鼠标移到图像上
将鼠标移动到支持工具提示文本的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();
}
});
}
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.*;
导入javax.swing.plaf.*;
导入javax.swing.UIManager.*;
公共类ToolTipPanel扩展了JPanel
{
公共工具面板()
{
setPreferredSize(新尺寸(200200));
setToolTipText(“”);
}
公共组件(图形g)
{
g、 setColor(Color.red);
g、 fillRect(0,0,100,200);
g、 setColor(Color.blue);
g、 fillRect(100,0100200);
}
@凌驾
公共字符串getToolTipText(MouseEvent e)
{
如果(如getX()<100)
返回“红色”;
其他的
返回“蓝色”;
}
@凌驾
公共点getToolTipLocation(MouseeEvent e)
{
点p=e.getPoint();
p、 y+=15;
返回p;
}
私有静态void createAndShowGUI()
{
JFrame=新JFrame(“SSCCE”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的ToolTipPanel());
frame.setLocationByPlatform(真);
frame.pack();
frame.setVisible(true);
}
公共静态void main(字符串[]args)
{
invokeLater(新的Runnable()
{
公开募捐
{
createAndShowGUI();
}
});
}
}
另一种方法是使用JXLayer在移动鼠标时绘制文本。查看Swing教程中的响应事件示例,以获取入门示例。如果我将其设置为null,是否仍保留网格布局?抱歉,我在问题中遗漏了这一点。JDialog的布局是GridLayout吗?是的,JDialog中的GridLayout中有两个图像由于注释部分的代码格式不正确,我将编辑我的问题,将其放在inI中。我也尝试了你的方法,通过更改JLabel的坐标以对应于鼠标的坐标,我将在下面的评论中发表这一点。请注意,我这样做时没有将格式更改为null。执行此操作后,我收到错误消息,表示类型ActionEvent的getX方法未定义。