Reputation: 177
As the title says, I want to be able to right-click lines I've drawn on Jpanel. Since those lines aren't Components I can't simply add MouseListener to them. Currently I'm drawing lines on my Jpanel with the following code:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (UserDrawnLine line : userDrawnLines) {
g.setColor(new Color(line.colorRValue,line.colorGValue, line.colorBValue));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(line.thickness));
g.drawLine(line.startPointX, line.startPointY, line.endPointX, line.endPointY);
}
}
This is my UserDrawnLine class:
public class UserDrawnLine {
public int startPointX;
public int startPointY;
public int endPointX;
public int endPointY;
public int colorRValue;
public int colorGValue;
public int colorBValue;
public float thickness;
public UserDrawnLine(int startPointX, int startPointY, int endPointX, int endPointY, int colorRValue,int colorGValue,int colorBValue, float thickness) {
this.startPointX = startPointX;
this.startPointY = startPointY;
this.endPointX = endPointX;
this.endPointY = endPointY;
this.colorRValue=colorRValue;
this.colorBValue=colorBValue;
this.colorGValue=colorGValue;
this.thickness=thickness;
}
}
I've been thinking about storing points through which the line goes and then reacting accordingly when user clicks on Jpanel on one of those points. However this doesn't seem like the best solution. Any better ones?
Upvotes: 0
Views: 292
Reputation: 8348
Create a Collection Lines and, using the Point
provided from the MouseEvent
in the MouseListener
, iterate over the Collection and check if the point is on each Line
. You may have to roll your own Line class and implement a contains
method (note that the Line2D cannot be used as it's contains method always returns false).
To determine if a Point P is on the line:
distance(P, A) + distance(P, B) = distance(A,B)
Where A and B are the line endpoints, and P is the test point. One can use an error term to allow for points that are near but not exactly on the Line (for instance, when using wider strokes to render, you might wish to increase this error term). Assuming your class has endpoints a and b:
public boolean contains(Point p, double error){
double dist = Math.sqrt(Math.pow(p.x - a.x, 2) + Math.pow(p.y - a.y, 2)) +
Math.sqrt(Math.pow(p.x - b.x, 2) + Math.pow(p.y - b.y, 2));
return Math.abs(dist - this.distance) <= error;
}
Upvotes: 1