如何使Graphics2D在鼠标悬停上绘制工具提示 [英] How do I make Graphics2D draw a tooltip on Mouse Hover

查看:109
本文介绍了如何使Graphics2D在鼠标悬停上绘制工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

so I have initialized each individual vertex as a JLabel and drawn the dot on the application with Graphics2D. However, I can't get a mouse listener to work with the graphic drawing for some reason. I am trying to get a tooltip to appear whenever the user has their mouse on the point (making an interractive graph).

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;
    }

}

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

I am hoping to get information written on the tooltip, so if you could give me information on how to draw it with text on it? Or maybe I have to initialise the tooltip as a panel? I am not sure, I need help with that

推荐答案

很难确切地知道要提出什么建议,但是首先要考虑一下Swing组件支持工具提示文本的事实,请参见

It's hard to know exactly what to suggest, but lets start with the fact the Swing components support tooltip text out of the box, see How to Use Tool Tips

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

This would suggest that all you really need to do is call setToolTipText and let the system do the rest.

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

However, based on the available code, I think you're abusing JLabel. Personally, I'd start with a JPanel, it's much more flexible and does't have the same overhead and complexity that JLabel does.

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

I would then start with a concept of a Vertex, which just holds information about the point

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;
    }

}

然后我将创建某种类型的可绘制"可以按照您想做的方式绘制Vertex的概念(我喜欢将这些事情去耦)

I'd then create some kind of "drawable" concept which can draw the Vertex the way you want to do (I like to decouple these things)

对我来说,我只需扩展Ellipse2D.Double即可绘制Vertex,它是自绘制的,并且内置了碰撞检测功能,对于您要实现的目标非常重要.

For me, I'd simply extend a Ellipse2D.Double to draw the Vertex, it is self drawing and has collision detection capabilities built in, very important for what you want to achieve.

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方法,这些方法将提供实现(我相信)是您的核心结果所需的核心功能...

I'd then simply override the getToolTipText(MouseEvent) and paintComponent methods, these would provide the core functionality needed to achieve (what I believe) is you core result...

@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)方法,可以轻松地用于确定鼠标(在这种情况下)是否位于顶点上.

As you can see, VertexPoint has a cool contains(Point) method, which can easily be used to determine if (in this case) the mouse is over a vertex or not.

因为那是一堆无语的杂音

Because that's a nice bunch of out of context mumbo-jumble

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;
            }

        }

    }

}

这篇关于如何使Graphics2D在鼠标悬停上绘制工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆