如何让Graphics2D在Mouse Hover上绘制工具提示

时间:2018-05-26 21:22:25

标签: 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;
    }

}

我希望获得工具提示上的信息,所以如果你能给我一些关于如何用文字绘制它的信息呢?或者我可能需要将工具提示初始化为面板?我不确定,我需要帮助

1 个答案:

答案 0 :(得分:1)

很难确切知道建议的内容,但让我们从Swing组件开箱即用的工具提示文本开始,请参阅How to Use Tool Tips

这表明您真正需要做的就是致电setToolTipText并让系统完成剩下的工作。

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

然后我会从Vertex的概念开始,它只包含关于点的信息

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

}

然后我会制作某种" drawable"可以按照你想要的方式绘制Vertex的概念(我喜欢将这些东西分开)

对我而言,我只是扩展Ellipse2D.Double以绘制Vertex,它是自绘图并内置了碰撞检测功能,对于您想要实现的目标非常重要。< / p>

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

        }

    }

}