Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Problem with zoom function

 
Veronique Kus
Ranch Hand
Posts: 41
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I'm trying to implement a zoom function for my application. I use a JComboBox in which the user sets the desired scaling. Before the drawing canvas is (re)painted in its paintComponent() function, i set the scale of the Graphics2D object to the scale set by the user (line 91 in the code below). Everything is drawn according to the scale so this works fine. However, my problem is that the mouse listener gets messed up when the scale is changed. For example, if I set scale to 200%, a mouse click which would normally be interpreted as hapenning at point (100, 100) is now taken to happen at (200, 200)ar.

The below code is a small program which illustrates my problem.



I tried setting the scale of the Graphics2D object back to 1 at the end of paintComponent function but it did not change anything. I would be really grateful for suggestions from solution(s) to my problem. Maybe I'm even approaching this problem in a completely wrong way and I shouldn't use the scaling to implement the zoom???
 
Campbell Ritchie
Sheriff
Posts: 48921
58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you tried the AffineTransform class?
If you use transforms, however, it may be a good idea to duplicate the Graphics object; there is a method in Graphics which I think is called create() which does that. The reason is to avoid tiny floating-point errors from accumulating. I have only had that problem with shearing transforms before, but I wouldn't take any chances.
 
Veronique Kus
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I tried AffineTransform but the result is the same :-(

Any other suggestions from anyone? If not solution to this particular obstacle, mayb someone has a proposition of a different implementation of the zoom tool?
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Veronique --

You need to apply the zoomScale to the mouse click coordinates before using them. If zoomScale is 2, then if you have a circle at 100, 100, you draw it at the screen coordinates 200, 200, right? Now, the question is, if you click at 200, 200, where do you want the circle to go? You want it to appear right where you clicked. What coordinates would a circle need to appear at screen coordinates 200, 200? That's right: 100, 100. Therefore you need to divide your mouse coordinates by the zoom factor before using them:

 
Veronique Kus
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks.
 
Ben Wood
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Veronique,

I work a lot with scaling 2D graphics in this way and I often handle the zooming myself, rather than use scaling. What I mean is that I transform the drawing coordinates of the various shapes "manually", rather than scaling the Graphics context.

I generally do this by multiplying or adding to the raw shape coordinates at the time they are drawn. This also enables me to handle panning/dragging as well as zoom.

The reason that I do this is because scaling affects the appearance of the shapes. For example, if you add these two lines to the end of your paintComponent() method:



you will see that the line thickness changes according to the zoom level. Maybe this is not a problem for your application, but for me the lines etc must always be the same thickness on the screen, regardless of the zoom setting.

Ben
 
Sumeda Viduranga
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ernest Friedman-Hill wrote:Veronique --

You need to apply the zoomScale to the mouse click coordinates before using them. If zoomScale is 2, then if you have a circle at 100, 100, you draw it at the screen coordinates 200, 200, right? Now, the question is, if you click at 200, 200, where do you want the circle to go? You want it to appear right where you clicked. What coordinates would a circle need to appear at screen coordinates 200, 200? That's right: 100, 100. Therefore you need to divide your mouse coordinates by the zoom factor before using them:



this works for me Thanks
 
Campbell Ritchie
Sheriff
Posts: 48921
58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shows that old threads can be useful
And welcome to the Ranch
 
Piet Souris
Rancher
Posts: 1259
26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I do not consider the given solution a nice one.

Much safer would be to save the current transform, and after
receiving a mouse click, translate the mouse coordinates
to the user coordinates with the help of this saved transform.
See the API for a useful method to do that.

Greetz,
Piet

edit: I just realized that I did not give this topic a thorough read.
So my reply may be completely irrelevant! If so, ignore it.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic