Как заставить Graphics2D нарисовать всплывающую подсказку на Mouse Hover - PullRequest
0 голосов
/ 27 мая 2018

, поэтому я инициализировал каждую отдельную вершину как 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 голосов
/ 27 мая 2018

Трудно точно сказать, что предложить, но давайте начнем с того факта, что компоненты Swing поддерживают текст всплывающей подсказки «из коробки», см. Как использовать подсказки

Это предполагаетвсе, что вам действительно нужно сделать, это позвонить по номеру 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;
    }

}

Я бы тогда создал какую-то "нарисованную" концепцию, которая может нарисовать Vertex так, как вы хотите (мне нравится отделять эти вещи)

Для меня я бы просто расширил 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;
            }

        }

    }

}
...