aspose file tools*
The moose likes Beginning Java and the fly likes Mouse listener question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Mouse listener question" Watch "Mouse listener question" New topic
Author

Mouse listener question

Paul Pearson
Greenhorn

Joined: Jan 15, 2008
Posts: 4
I'm writing a program using Java2D which displays a 3D cube and responds to mouse clicks and movement.

I've got a JFrame containing a JComponent. This JComponent possesses variables holding information like the coordinates of cube vertices and such like. I want to detect mouse clicks and mouse movements on this component, so I've extended the MouseAdapter class and added an instance to the JComponent. So far so good - it detects clicks and everything else fine.

But within the mouseClicked() method that I'm overriding, I want to access
the coordinate variables in the JComponent class, so that I can tell, for
example, if a mouse click is close to a cube vertex.

I can see a couple of ways I could get round this, for example implementing the MouseListener interface on the JComponent class itself instead, or else making the variables that I want access to static. But isn't there another way that is less of a fudge, which allows me to keep the listener as a separate class?

Thanks,
Paul
Justin Fox
Ranch Hand

Joined: Jan 24, 2006
Posts: 802
Even though the Cube looks "3D" it is drawn in 2D so if you have the verticies stored somewhere, and the cube never rotates or translates, couldn't you just use the MouseEvent.getX() and MouseEvent.getY() and compare those values to the stored verticy coordinates?

even if the cube rotated/translated you could just update the stored verticies each time and the above solution should work just fine.

and If you have the cube say in a JPanel, which in turn is inside another JPanel, you just add the "mouseListener" to whatever component you want to
listen for the clicks and such.

I'm not sure how the cube works, if it is a predefined class or if you just drew some squares, and then connected them with lines. Either way this should work, because if you just have a Cube object and that type inherits from JComponent you should be able to add a mouseListener directly to it.

Justin Fox


You down with OOP? Yeah you know me!
Mark Newton
Ranch Hand

Joined: Jan 31, 2006
Posts: 129
Justin, I might be wrong, but I read the question differently - I think Paul's asking how to access the stored co-ordinates, to be able to compare them with the MouseEvent.getX() / getY() results.

If that's right, Paul, then I would do it by giving the MouseAdapter a constructor, which takes your component as an argument. That way, when you instantiate the MouseAdapter, you just pass it the component. If your co-ordinate variables in the component are public, you can access them directly, otherwise, just add accessors (get's).

So, you'd have something like:


Sorry if this wasn't what you were asking...

[Edited to add a few extra comments]
[ January 16, 2008: Message edited by: David Payne ]
Paul Pearson
Greenhorn

Joined: Jan 15, 2008
Posts: 4
Thanks Justin and David!

David, I think your solution could well work. In the end though, I completed the program by implementing the interfaces MouseInputListener and MouseWheelListener on the class with the variables I needed to access. I'm so new to Java that I wasn't aware you could implement two interfaces on the same class, before I did some research.

In fact the cube does rotate and translate. It doesn't just translate the 2D image, it translates the representation of the cube in 3D space and draws it exactly as you would see it, in perspective. It assumes the viewer's eye is in the middle of the window according to the original window size (and 2200 pixels distance from the screen), so if you resize the window your eye is probably in the wrong place. I'm quite proud of the program so I'm posting the full source code below. It's made up of four classes, so it's probably best if you save them in four separate files, called respectively MyFrame.java, MyComponent.java, Point3D.java and PlanePoint.java. Look for the comments in caps to see where to separate the files. Most of the code isn't properly commented though I'm afraid. I'm sorry if this isn't the accepted place to post long source code. I'm very new here!

I think there are bits of code here that aren't needed (used for testing purposes). I could also save memory by cutting down on variables (lots of variables helped to get it clear in my head), and it may not be the most efficient way of doing things, but the vector maths is pretty sound (I'm a mathematician). You can't beat that feeling you get when you try a piece of code and it works! I'd be interested to see what people think. Please post comments or questions.

Finally here's how you get it to work:
Originally you see just the face of the cube that is nearest you.
Click and drag anywhere on the cube (or window) to translate it.
Roll the mouse wheel to translate the cube towards or away from you.
But best of all, click and drag on any of the vertices to rotate the cube. That's the bit that took the most thought and effort!

Mark Newton
Ranch Hand

Joined: Jan 31, 2006
Posts: 129
Hi Paul,

Just had a play with your cube app - most impressive, well done

Dave.
Paul Pearson
Greenhorn

Joined: Jan 15, 2008
Posts: 4
Thanks David!
Just finished a fully commented final version that responds correctly to window resizing, and with all the unused variables and methods removed. Give me a shout if anyone wants it.
Neel Taylor
Greenhorn

Joined: Sep 05, 2007
Posts: 6
I would very definitely love to see your final version. Thanks for sharing this- I am a beginner myself and this is exactly the kind of thing I want to be able to do. Your code is a wonderful example.
Matt Fielder
Ranch Hand

Joined: Oct 27, 2004
Posts: 158
I'd love to see it!
Paul Pearson
Greenhorn

Joined: Jan 15, 2008
Posts: 4
Ok here it is. Thanks for the appreciation!

It's tricky to explain exactly how it works, but parts of it make use of the cross product and dot (also called scalar) product of two vectors. These can be looked up on wikipedia.

For the rotation, imagine the vertices as lying on a sphere with centre the same as the centre of the cube. A point on or near the cube on the screen corresponds to a point (well really two points!) on the sphere. For a mouse drag from a vertex, the program works out how the sphere has been rotated and then rotates all vertices accordingly.

 
Don't get me started about those stupid light bulbs.
 
subject: Mouse listener question