Reputation: 21
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
Upvotes: 0
Views: 2298
Reputation: 347332
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
This would suggest that all you really need to do is call setToolTipText
and let the system do the rest.
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.
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;
}
}
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)
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;
}
}
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();
}
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;
}
}
}
}
Upvotes: 2