How can I implement a Zoom Panel with Java Swing libraries -
i've implemented jframe java swing libraries visualize map. i'd realize zoom function within frame. code of jframe:
package components; import java.awt.borderlayout; import java.awt.container; import javax.swing.jframe; import javax.swing.jscrollpane; public class myframe extends jframe { private static final long serialversionuid = 1l; private container contentpane; public static final int startwidth = 1280; public static final int startheight = 800; public static mypanel earthpanel; public myframe(){ initcomponents(); } public void initcomponents(){ contentpane = getcontentpane(); this.settitle("tle graphic propagator"); this.setdefaultcloseoperation(jframe.exit_on_close); this.setsize(startwidth, startheight); this.setlocation(0,0); this.setlayout(new borderlayout()); earthpanel = new mypanel(startwidth,startheight); jscrollpane scroll = new jscrollpane(earthpanel, jscrollpane.vertical_scrollbar_always, jscrollpane.horizontal_scrollbar_always); myslider slider = new myslider(); contentpane.add(scroll, borderlayout.center); contentpane.add(slider, borderlayout.south); } }
as can see above, frame contains jpanel in jscrollpane , jslider use zoom function. follows code of panel..
package components; import java.awt.dimension; import java.awt.graphics; import java.awt.graphics2d; import java.awt.image.bufferedimage; import java.io.file; import javax.imageio.imageio; import javax.swing.jpanel; public class mypanel extends jpanel{ private static final long serialversionuid = 1l; private bufferedimage img; private int width, height; private string path = "images/earth1280x800.jpg"; private static final int update_rate = 10; //#volte al secondo public mypanel(int larghezzaframe, int altezzaframe){ width = larghezzaframe; height = altezzaframe; this.setpreferredsize(new dimension(width, height)); img = loadimage(); } public bufferedimage loadimage() { bufferedimage bimg = null; bufferedimage ret = null; try { bimg = imageio.read(new file(path)); } catch (exception e) { e.printstacktrace(); } ret = new bufferedimage(bimg.getwidth(), bimg.getheight(), bufferedimage.type_int_argb); graphics2d g = ret.creategraphics(); g.drawimage(bimg, 0, 0, null); g.dispose(); return ret; } @override protected void paintcomponent(graphics g) { setopaque(false); graphics2d g2d = (graphics2d)g; g2d.scale(myslider.scale, myslider.scale); g2d.drawimage(img, 0, 0, null); super.paintcomponent(g2d); } }
..and slider's one:
package components; import java.awt.dimension; import javax.swing.jslider; import javax.swing.event.changeevent; import javax.swing.event.changelistener; public class myslider extends jslider implements changelistener{ private static final long serialversionuid = 1l; public static double scale = 1; public myslider(){ super(jslider.horizontal, 100, 400, 100); setmajortickspacing(50); setminortickspacing(10); setpaintticks(true); setpaintlabels(true); addchangelistener(this); } @override public void statechanged(changeevent arg0) { int value = ((jslider) arg0.getsource()).getvalue(); scale = value/100.0; myframe.earthpanel.setpreferredsize(new dimension((int)(myframe.startwidth * myslider.scale),(int)(myframe.startheight * myslider.scale))); myframe.earthpanel.repaint(); } }
to run code, need insert following main function:
package main; import components.myframe; public class mainpersonalframe { public static void main(string[] args){ myframe frame = new myframe(); frame.setvisible(true); } }
note: necessary insert package "images" in same path of source code image called "earth1280x800.jpg" that.
the problem comes out when use zoom function, scrolling right/left , up/down, image not contained frame anymore. i'd automatic refresh of scrollbars , image doesn't come out borders. how should it?
thanks everyone.
i'm not 100% sure problem is, suspect issue you're not changing preferred size of image jpanel when image changes size. if so, solution override getpreferredsize()
in image displaying jpanel , return dimension matches of zoomed image.
edit, no, sort of this, you're not revalidating nor repainting jscrollpane's viewport, , must do.
import java.awt.borderlayout; import java.awt.container; import java.awt.dimension; import java.awt.graphics; import java.awt.graphics2d; import java.awt.image.bufferedimage; import java.io.ioexception; import java.net.url; import javax.imageio.imageio; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.jscrollpane; import javax.swing.jslider; import javax.swing.event.changeevent; import javax.swing.event.changelistener; public class mainpersonalframe { public static void main(string[] args) { myframe frame = new myframe(); frame.setvisible(true); } } class myframe extends jframe { private static final long serialversionuid = 1l; private container contentpane; public static final int startwidth = 1280; public static final int startheight = 800; // !! should private , not static private mypanel earthpanel; // !! should field private jscrollpane scroll; public myframe() { initcomponents(); } public void initcomponents() { contentpane = getcontentpane(); this.settitle("tle graphic propagator"); this.setdefaultcloseoperation(jframe.exit_on_close); // !! avoid setting sizes if possible this.setsize(startwidth, startheight); this.setlocation(0, 0); this.setlayout(new borderlayout()); earthpanel = new mypanel(startwidth, startheight); // !! again, scroll field scroll = new jscrollpane(earthpanel, jscrollpane.vertical_scrollbar_always, jscrollpane.horizontal_scrollbar_always); myslider slider = new myslider(this); contentpane.add(scroll, borderlayout.center); contentpane.add(slider, borderlayout.south); } // !! avoid having classes directly manipulate other class's fields public void setearthpanelsize(dimension size) { earthpanel.setpreferredsize(size); } // !! allow other classes ability revalidate/repaint viewport public void revalidateviewport() { scroll.getviewport().revalidate(); scroll.getviewport().repaint(); } } class mypanel extends jpanel { private static final long serialversionuid = 1l; private bufferedimage img; private int width, height; // !! changes can run program // !! internet image // !! private string path = "images/earth1280x800.jpg"; private string urlpath = "http://image.desk7.net/" + "space%20wallpapers/1422_1280x800.jpg"; // !! private static final int update_rate = 10; // !! never used public mypanel(int larghezzaframe, int altezzaframe) { setopaque(false); // !! should here width = larghezzaframe; height = altezzaframe; this.setpreferredsize(new dimension(width, height)); img = loadimage(); } public bufferedimage loadimage() { bufferedimage bimg = null; bufferedimage ret = null; try { url imgurl = new url(urlpath); // !! bimg = imageio.read(new file(path)); // !! bimg = imageio.read(imgurl); // !! use image available // !! } catch (exception e) { // e.printstacktrace(); } catch (ioexception e) { // !! use more specific exception e.printstacktrace(); } ret = new bufferedimage(bimg.getwidth(), bimg.getheight(), bufferedimage.type_int_argb); graphics2d g = ret.creategraphics(); g.drawimage(bimg, 0, 0, null); g.dispose(); return ret; } @override protected void paintcomponent(graphics g) { // !! shouldn't in paintcomponent: // !! setopaque(false); graphics2d g2d = (graphics2d) g; g2d.scale(myslider.scale, myslider.scale); g2d.drawimage(img, 0, 0, null); super.paintcomponent(g2d); } } class myslider extends jslider implements changelistener { private static final long serialversionuid = 1l; public static double scale = 1; private myframe myframe; public myslider(myframe myframe) { super(jslider.horizontal, 100, 400, 100); this.myframe = myframe; setmajortickspacing(50); setminortickspacing(10); setpaintticks(true); setpaintlabels(true); addchangelistener(this); } @override public void statechanged(changeevent arg0) { int value = ((jslider) arg0.getsource()).getvalue(); scale = value / 100.0; int w = (int) (myframe.startwidth * myslider.scale); int h = (int) (myframe.startheight * myslider.scale); dimension size = new dimension(w, h); myframe.setearthpanelsize(size); // !! myframe.revalidateviewport(); // !! // !! myframe.earthpanel.repaint(); // no, don't } }
Comments
Post a Comment