Results 1 to 4 of 4
 06202011, 08:31 PM #1Member
 Join Date
 Jun 2011
 Posts
 19
 Rep Power
 0
Repositioning components based on mouse position
Hello, I am implementing a zoom feature for a JPanel that is populated with many smaller JPanels.
The premise is: when the user spins the mouse scroll wheel the "zoomPercent" is increased/decreased and then all the child components are resized based on their "defaultSize" and the new "zoomPercent" value. This all works fine. Now the problem I've run into is how to get the child components to relocate towards the mouse pointer based on the "zoomPercent" to give the illusion of zooming. I believe the Trig involved requires the use of the AAA Similar Triangle Theorem but I can't quite figure it out. What I have right now \/ is giving me odd results. When I scroll the mouse wheel forward the elements seem to move towards the mouse pointer, but they don't move away from the pointer when I scroll backwards on the scroll wheel. Eventually, after scrolling forwards and backwards a few times the child components will all be perfectly overlapped and jump to the mouse pointer's position when I try scrolling. Any guidance?
Java Code:private int zoomPercent = 100; public void mouseWheelMoved(MouseWheelEvent e) { int oldZoomPercent = Math.max(1, zoomPercent); int notches = e.getWheelRotation(); int increment = 50; zoomPercent += increment * notches; zoomPercent = Math.max(0, zoomPercent); //mouse position int x = e.getX(); int y = e.getY(); for (Node node: nodes) { int newWidth = node.defaultWidth * zoomPercent / 100; int newHeight = node.defaultHeight * zoomPercent / 100; node.setSize(newWidth, newHeight); int nodeX = node.getLocation().x; int nodeY = node.getLocation().y; int dx = Math.abs(x  nodeX); int dy = Math.abs(y  nodeY); //distance between component and mouse pointer double hyp = Math.sqrt(dx * dx + dy * dy); //angle of hypotenuse double angle = Math.asin(dy / hyp); //new hypotenuse length double newHyp = hyp * zoomPercent / oldZoomPercent; //horizontal component of hypotenuse double sin = Math.sin(angle); //vertical component of hypotenuse double cos = Math.cos(angle); //change in horizontal component dx = (int) Math.abs(sin * newHyp  sin * hyp); //change in vertical component dy = (int) Math.abs(cos * newHyp  cos * hyp); int finalX, finalY = 0; if (nodeX > x) { finalX = x + dx; } else { finalX = x  dx; } if (nodeY > y) { finalY = y + dy; } else { finalY = y  dy; } node.setLocation(finalX, finalY); } validate(); }
 06212011, 01:53 AM #2Moderator
 Join Date
 Feb 2009
 Location
 New Zealand
 Posts
 4,611
 Rep Power
 12
If you want to perform an enlargement whose center is at the mouse position, I'm not sure I would bother with the angle.
* Find nodeXx, the xdistance to the node. (Don't Math.abs() it because the sign is important)
* Multiply this "delta" by the scale factor
* Add the result back to x to get the new xposition of the node
* Repeat for y
 06212011, 03:33 AM #3Member
 Join Date
 Jun 2011
 Posts
 19
 Rep Power
 0
Very much appreciated. This was my first inclination but I made errors in other places and assumed my approach was incorrect.
Well now it works wonderfully! The zoom effect is perfect. Now there's just one little hickup. If I zoom out so far that the nodes actually disappear
when I zoom back in and they reappear they are all occupying the same exact position and hence, are overlapping.
Java Code:public void mouseWheelMoved(MouseWheelEvent e) { double oldZoomPercent = Math.max(1, zoomPercent); int notches = e.getWheelRotation(); int increment = 50; zoomPercent += increment * notches; zoomPercent = Math.max(0, zoomPercent); //mouse position int x = e.getX(); int y = e.getY(); for (Node node: nodes) { int newWidth = (int) (node.defaultWidth * zoomPercent / 100); int newHeight = (int) (node.defaultHeight * zoomPercent / 100); node.setSize(newWidth, newHeight); int nodeX = node.getLocation().x; int nodeY = node.getLocation().y; int dx = (int) ((nodeX  x) * zoomPercent / oldZoomPercent); int dy = (int) ((nodeY  y) * zoomPercent / oldZoomPercent); node.setLocation(x + dx, y + dy); } validate(); }
Last edited by robbie.26; 06212011 at 03:42 AM.
 06212011, 06:55 AM #4
Looks like the usual integer math 'problem'. I think you'll have to maintain a pair of double variables for the 'last computed location' of the node. I would also declare dx and dy as double, and cast the final incremented value in setLocation.
Java Code:// x, dx, y, dy are of type double // x and y are retained, possibly as custom fields of 'node' x += dx; y += dy; node.setLocation((int) x, (int) y);
Similar Threads

Problem with determing mouse position!!!
By G.rocks in forum New To JavaReplies: 6Last Post: 07152010, 05:09 PM 
repositioning
By ashish9590 in forum NetBeansReplies: 2Last Post: 02142010, 07:42 AM 
get position in string from caret position
By helloworld111 in forum AWT / SwingReplies: 5Last Post: 02192009, 02:36 AM 
How to get mouse hit position in a textlayout using TextHitInfo class
By Java Tip in forum java.awtReplies: 0Last Post: 06252008, 10:32 AM 
Use the mouse position
By susan in forum Java AppletsReplies: 1Last Post: 07282007, 11:10 PM
Bookmarks