java - JScrollPane setViewPosition After "Zoom" -


the code have here using mouseadapter listen user "draw" box around area of image zoom in on , calculate ratio of box image. resizes image calculated ratio. part works.

the issue having making jscrollpane view appear if still @ same top left position after image has been resized. have tried several methods seem have gotten close result want not exactly.

this listener finds scale ratio , sets position:

import java.awt.event.mouseadapter; import java.awt.event.mouseevent; import java.awt.graphics; import java.awt.point;  import javax.swing.jscrollpane; import javax.swing.jviewport; import javax.swing.jcomponent;  public class dynamiczoom extends mouseadapter {  private point start; private point end; private double zoom = 1.0; private jscrollpane pane; private jviewport port;   public void mousepressed(mouseevent e) {     if(e.getbutton() == mouseevent.button1) {         this.pane = (jscrollpane)e.getsource();         this.port = pane.getviewport();         start = e.getpoint();     } }  public void mousereleased(mouseevent e) {     if(this.pane != null) {         point curr = this.port.getviewposition();         end = e.getpoint();          imagecomponent canvas = (imagecomponent)this.port.getview();         zoom = canvas.getscale();         double factor = 0.0;         double selectedwidth = math.abs(end.getx() - start.getx());         double selectedheight = math.abs(end.gety() - start.gety());         if(selectedwidth > selectedheight)             factor = this.port.getwidth() / selectedwidth;         else             factor = this.port.getheight() / selectedheight;          zoom *= factor;         int x = (int)((start.x+curr.x)*zoom);         int y = (int)((start.y+curr.y)*zoom);          point point = new point(x, y);          ((imagecomponent)(this.port.getview())).setscale(zoom);          resizeviewport.resize(pane);         this.port.setviewposition(point);     } }  public void mousedragged(mouseevent e) {     if(this.pane != null) {         graphics g = this.port.getgraphics();         int width = this.start.x - e.getx();         int height = this.start.y - e.gety();          int w = math.abs( width );         int h = math.abs( height );         int x = width < 0 ? this.start.x : e.getx();         int y = height < 0 ? this.start.y : e.gety();         g.drawrect(x, y, w, h);         this.port.repaint();     } } 

}

this imagecomponent resizes , displays image:

import java.awt.dimension; import java.awt.graphics; import java.awt.graphics2d; import java.awt.image.bufferedimage;  import javax.swing.jcomponent;  public class imagecomponent extends jcomponent { private static final long serialversionuid = 1975488835382044371l; private bufferedimage img = null;  private double scale = 0.0;  public imagecomponent() {}  public imagecomponent(bufferedimage img) {     this.displaypage(img); }  @override public void paint(graphics g) {     graphics2d g2 = ((graphics2d)g);     if(this.img != null) {         int width = (int)(this.img.getwidth() * this.scale);         int height = (int)(this.img.getheight() * this.scale);         this.setpreferredsize(new dimension(width, height));         g2.drawimage(this.img, 0, 0, width, height, null, null);         g2.dispose();     } }  public void displaypage(bufferedimage pic) {     if(img != null) {         this.img = pic;     } }  public bufferedimage getpage() {     return this.img; }  public void setscale(double ratio) {     if(ratio > .04) {         this.scale = ratio;         this.repaint();     } }  public double getscale() {     return this.scale; } } 

the resizeviewport forces viewport show entire imagecomponent when scaled because otherwise clip image @ size was:

import java.awt.dimension;  import javax.swing.jscrollpane; public class resizeviewport { public static void resize(jscrollpane scroll) {     int vw = scroll.getwidth()-scroll.getverticalscrollbar().getwidth();     int vh = scroll.getheight()-scroll.gethorizontalscrollbar().getheight();     scroll.getviewport().setviewsize(new dimension(vw, vh)); } } 

it turns out there nothing wrong math used calculate position or way designed code. problem imagecomponent still painting in thread when position being calculated; therefore returning "false" values getwidth() , getheight() methods. solved issue using following code:

eventqueue.invokelater(new runnable() {    public void run() {       port.setviewposition(new point(x,y));    } }); 

this allows painting finish before trying calculate size of image , setting position in jscrollpane. problem solved. still throw out people took time @ least review issue.


Comments

Popular posts from this blog

c++ - Convert big endian to little endian when reading from a binary file -

C#: Application without a window or taskbar item (background app) that can still use Console.WriteLine() -

unicode - Are email addresses allowed to contain non-alphanumeric characters? -