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
Post a Comment