Hi,
I've made a class which extends polygon and implements mouselistener.
When i instantiate one of these classes onto a canvas, the
mouselisteners for pressed, released, clicked etc all work fine on the
filling of the polygon, however not on the stroke (border/outline).
This means if i have a rectangle with a height of 0 (i.e. it appears as
a line) rolling the mouse over it fires no events.
Why is this, and more importantly, is there anything i can do about it?
Ill post my code if its needed, but theres not much to it.
It simply has a method for each mouse event, and calls the respective
function on a mouselistener object when fired.
Many thanks,
Andrew Bullock
Chris Smith - 16 Mar 2005 00:28 GMT
> I've made a class which extends polygon and implements mouselistener.
>
> When i instantiate one of these classes onto a canvas, the
> mouselisteners for pressed, released, clicked etc all work fine on the
> filling of the polygon, however not on the stroke (border/outline).
The fact that it happens to be your Polygon subclass that implements
MouseListener is irrelevant here. What are you adding the MouseListener
to? What is the code in the MouseListener?
If you add the MouseListener to the Canvas, you will receive ALL mouse
events for that canvas, NOT just those that occur within the polygon.
That makes me suspect that you are, in fact, getting the notification,
but you've got code to cull it out, and that code is wrong.
However, until you post some code, all I can do is speculate.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
Andrew Bullock - 16 Mar 2005 00:57 GMT
> However, until you post some code, all I can do is speculate.
Hi,
Sure..
I'ts based on this code here:
http://users.erols.com/ziring/java-src/SensitivePolygon.java
Which also suffers from the same problem (try the bottom of the red square)
Any help on clearing this up would be greatly appreciated
Thanks
Andrew Bullock
Chris Smith - 17 Mar 2005 01:49 GMT
> When i instantiate one of these classes onto a canvas, the
> mouselisteners for pressed, released, clicked etc all work fine on the
[quoted text clipped - 4 lines]
>
> Why is this, and more importantly, is there anything i can do about it?
Your processPoint method uses Polygon.contains to check whether the
given point is included in the polygon. That method checks to see if a
point is inside of the given polygon. Therefore, you detect points
inside of the polygon, and not points outside of the polygon.
Unfortunately, the alternative is much harder.
If you want to detect when the mouse is on the border of a polygon, then
you first need to know how large that border really is. Since the
Graphics object in SensitivePolygon.paint comes from outside of
SensitivePolygon, that attribute isn't really defined from inside your
class... someone could have called Graphics2D.setStroke to change it.
The easiest solution to this problem is to make the border width a
property of SensitivePolygon and adopt a policy of setting it before
drawing the polygon.
Then you need to determine if a point would be inside of the border that
will be drawn around the rectangle. That's geometrically equivalent to
asking whether a circle centered at that point, with a diameter equal to
the border width, intersects the area inside the polygon. Fortunately,
Java2D provides constructive area geometry for you, in the form of the
java.awt.geom.Area class. The resulting code looks something like this:
boolean hit;
int x = mouseEvent.getX();
int y = mouseEvent.getY();
float r = borderWidth / 2.0f;
Ellipse2D circle = new Ellipse2D.Float(x - r, y - r, 2 * r, 2 * r);
Area a = new Area(this);
a.intersect(new Area(circle));
hit = !a.isEmpty();
At the end of this, "hit" will indicate whether the point falls either
within the polygon or on one of its borders (true), or outside of either
(false).
Your updated paint will need to set the Stroke before drawing, so this
goes around SensitivePolygon's paint method:
Graphics2D g2d = (Graphics2D) g;
Stroke oldStroke = g2d.getStroke();
g2d.setStroke(new BasicStroke(borderWidth));
...
g2d.setStroke(oldStroke);
> Ill post my code if its needed, but theres not much to it.
> It simply has a method for each mouse event, and calls the respective
> function on a mouselistener object when fired.
Having seen your code, I beg to differ. The problem you are having is
*critically* dependent on your code... namely, that you're relying on
Polygon.contains to tell you if a point intersects a polygon. There's
no way anyone could have answered your question without access to your
source code.

Signature
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation