java - 如何让 Graphics2D 在鼠标悬停时绘制工具提示

标签 java swing user-interface graphics graphics2d

因此,我将每个单独的顶点初始化为 JLabel,并使用 Graphics2D 在应用程序上绘制点。但是,由于某种原因,我无法让鼠标监听器处理图形绘制。我试图在用户将鼠标放在该点上时显示工具提示(制作交互式图表)。

package GUI;

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;

    import javax.swing.JLabel;

    @SuppressWarnings("serial")
    public class Vertex extends JLabel {

    int x;
    int y;
    private int pointWidth;


    public Vertex(int x, int y, int pointWidth, Graphics2D g2) {

        g2.fillOval(x, y, pointWidth, pointWidth);

        //This above works

        setLocation(x, y);
        setSize(pointWidth, pointWidth);

        addMouseMotionListener(new MouseMotionListener() {
            @Override //This below doesn't work, but it does print out correct coordinates
            public void mouseMoved(MouseEvent event) {
                //double x = event.getPoint().getX();
                //double y = event.getPoint().getY();
                System.out.println(x+pointWidth/2+"    "+y+pointWidth/2);

                //Graphics g2 = getGraphics();

                g2.setColor(new Color(0,0,0,250));
                g2.fillRect(x, y, 100, 100);

                g2.dispose();
            }

            @Override
            public void mouseDragged(MouseEvent event) {
                //do nothing idc
            }
        });

    }

    public int getPointWidth() {
        return pointWidth;
    }

    public void setPointWidth(int pointWidth) {
        this.pointWidth = pointWidth;
    }

}

我希望获得工具提示上写的信息,所以您能否给我有关如何在其上绘制文本的信息?或者也许我必须将工具提示初始化为面板?我不确定,我需要帮助

最佳答案

很难确切地知道该建议什么,但让我们从 Swing 组件支持开箱即用的工具提示文本这一事实开始,请参阅 How to Use Tool Tips

这表明您真正需要做的就是调用 setToolTipText 并让系统完成其余的工作。

但是,根据可用的代码,我认为您正在滥用 JLabel。就我个人而言,我会从 JPanel 开始,它更加灵活,并且没有 JLabel 那样的开销和复杂性。

然后我将从顶点的概念开始,它只保存有关点的信息

public class Vertex {
    private Point point;

    public Vertex(Point point) {
        this.point = point;
    }

    public Point getPoint() {
        return point;
    }

    @Override
    public String toString() {
        return "Vertex @ " + getPoint().x + "x" + getPoint().y;
    }

}

然后我会创建某种“可绘制”概念,它可以按照您想要的方式绘制顶点(我喜欢将这些东西解耦)

对我来说,我只需扩展一个Ellipse2D.Double来绘制Vertex,它是自绘制的并且内置了碰撞检测功能,这对于什么非常重要你想要实现的目标。

public class VertexPoint extends Ellipse2D.Double {
    private Vertex vertex;

    public VertexPoint(Vertex vertex) {
        super(vertex.getPoint().x - 5, vertex.getPoint().y - 5, 10, 10);
        this.vertex = vertex;
    }

    public Vertex getVertex() {
        return vertex;
    }

}

然后我只需重写 getToolTipText(MouseEvent)paintComponent 方法,这些方法将提供实现(我相信)是您的核心结果所需的核心功能...

@Override
public String getToolTipText(MouseEvent event) {
    for (VertexPoint vp : verticies) {
        if (vp.contains(event.getPoint())) {
            return vp.getVertex().toString();
        }
    }
    return null;
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    for (VertexPoint vertex : verticies) {
        g2d.fill(vertex);
    }
    g2d.dispose();
}

如您所见,VertexPoint 有一个很酷的 contains(Point) 方法,可以轻松地用于确定(在本例中)鼠标是否位于某个对象上是否有顶点。

可运行示例...

因为这是一堆断章取义的胡言乱语

Tooltip hover

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Vertex {
        private Point point;

        public Vertex(Point point) {
            this.point = point;
        }

        public Point getPoint() {
            return point;
        }

        @Override
        public String toString() {
            return "Vertex @ " + getPoint().x + "x" + getPoint().y;
        }

    }

    public class TestPane extends JPanel {

        private List<VertexPoint> verticies;

        public TestPane() {
            verticies = new ArrayList<>(25);
            Random rnd = new Random();
            for (int index = 0; index < 10; index++) {
                int x = rnd.nextInt(200 - 10);
                int y = rnd.nextInt(200 - 10);
                add(new Vertex(new Point(x, y)));
            }
            setToolTipText("");
        }

        public void add(Vertex vertex) {
            verticies.add(new VertexPoint(vertex));
        }

        @Override
        public String getToolTipText(MouseEvent event) {
            for (VertexPoint vp : verticies) {
                if (vp.contains(event.getPoint())) {
                    return vp.getVertex().toString();
                }
            }
            return null;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (VertexPoint vertex : verticies) {
                g2d.fill(vertex);
            }
            g2d.dispose();
        }

        public class VertexPoint extends Ellipse2D.Double {
            private Vertex vertex;

            public VertexPoint(Vertex vertex) {
                super(vertex.getPoint().x - 5, vertex.getPoint().y - 5, 10, 10);
                this.vertex = vertex;
            }

            public Vertex getVertex() {
                return vertex;
            }

        }

    }

}

关于java - 如何让 Graphics2D 在鼠标悬停时绘制工具提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50547097/

相关文章:

java - 单选按钮无法正确显示

java - 以编程方式关闭当前显示的 Java Swing JDialog 框

java - 在 JTextPane 中选择多个项目

java - 如何从单击按钮的代码中进行调用?

java - 我们怎样才能得到在一定范围内,int能被2整除的最大次数

java - 单击按钮时在 JPanel 上绘制图像

java - Java 中 MVC 的类结构和位置

Java GUI 布局不太正确

java - 带有 Intellisense 的 Web UI

java - 如何使用 Selenium TestNG 和 Java 转换和匹配背景颜色 RGB(255, 255, 255) 与#fff