java - Add a background image to JPanel with rounded corners -
i've extended jpanel use in project want appear more "3d". that's bosses' way of requiring shadowing , rounded corners on components. that's been accomplished shown on many online examples. did this:
public class roundedpanel extends jpanel { protected int _strokesize = 1; protected color _shadowcolor = color.black; protected boolean _shadowed = true; protected boolean _highquality = true; protected dimension _arcs = new dimension(30, 30); protected int _shadowgap = 5; protected int _shadowoffset = 4; protected int _shadowalpha = 150; protected color _backgroundcolor = color.light_gray; public roundedpanel() { super(); setopaque(false); } @override public void setbackground(color c) { _backgroundcolor = c; } @override protected void paintcomponent(graphics g) { super.paintcomponent(g); int width = getwidth(); int height = getheight(); int shadowgap = this._shadowgap; color shadowcolora = new color(_shadowcolor.getred(), _shadowcolor.getgreen(), _shadowcolor.getblue(), _shadowalpha); graphics2d graphics = (graphics2d) g; if(_highquality) { graphics.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on); } if(_shadowed) { graphics.setcolor(shadowcolora); graphics.fillroundrect(_shadowoffset, _shadowoffset, width - _strokesize - _shadowoffset, height - _strokesize - _shadowoffset, _arcs.width, _arcs.height); } else { _shadowgap = 1; } graphics.setcolor(_backgroundcolor); graphics.fillroundrect(0, 0, width - shadowgap, height - shadowgap, _arcs.width, _arcs.height); graphics.setstroke(new basicstroke(_strokesize)); graphics.setcolor(getforeground()); graphics.drawroundrect(0, 0, width - shadowgap, height - shadowgap, _arcs.width, _arcs.height); graphics.setstroke(new basicstroke()); } }
i creating test frame following code:
public class uitest { private static jframe mainframe; private static imagepanel mainpanel; public static void main(string[] args) { eventqueue.invokelater(new runnable() { public void run() { mainframe = new jframe(); mainframe.setvisible(true); try { mainpanel = new imagepanel(imageio.read(this.getclass().getresource("/content/diamondplate_light.jpg"))); //mainpanel.setbounds(0, 0, 800, 600); } catch(ioexception e) { } mainpanel.setlayout(null); roundedpanel rpanel = new roundedpanel(); rpanel.setbounds(10, 10, 200, 200); rpanel.setbackground(new color(168, 181, 224)); mainpanel.add(rpanel); rpanel = new roundedpanel(); rpanel.setbounds(220, 10, 560, 200); rpanel.setbackground(new color(168, 224, 168)); mainpanel.add(rpanel); rpanel = new roundedpanel(); rpanel.setbounds(10, 220, 770, 300); rpanel.setbackground(new color(224, 168, 168)); mainpanel.add(rpanel); mainframe.setsize(800, 600); mainframe.getcontentpane().add(mainpanel); } }); } }
and results in (sans background image of jframe
's contentpane
:
what generate red, green, , blue panels rounded corners, filled different image instead of color
. still want rounded corners, i'm unsure of how this.
if i've got large texture, can "clip" piece of out in size , shape of roundedpanel
? need evaluate this, since occurred me typed, if can create piece of geometry used in graphics.fillroundrect(...)
, clip image, work.
are there other ways of doing i'm missing? i'd appreciate feedback might able offer. thanks.
edit:
based upon idea in selected solution below, i've got following results:
it needs whipped shape production , background images poorly chosen, demo, following roundedpanel
code gets above results:
public class roundedpanel extends jpanel { protected int strokesize = 1; protected color _shadowcolor = color.black; protected boolean shadowed = true; protected boolean _highquality = true; protected dimension _arcs = new dimension(30, 30); protected int _shadowgap = 5; protected int _shadowoffset = 4; protected int _shadowalpha = 150; protected color _backgroundcolor = color.light_gray; protected bufferedimage image = null; public roundedpanel(bufferedimage img) { super(); setopaque(false); if(img != null) { image = img; } } @override public void setbackground(color c) { _backgroundcolor = c; } @override protected void paintcomponent(graphics g) { super.paintcomponent(g); int width = getwidth(); int height = getheight(); int shadowgap = this._shadowgap; color shadowcolora = new color(_shadowcolor.getred(), _shadowcolor.getgreen(), _shadowcolor.getblue(), _shadowalpha); graphics2d graphics = (graphics2d) g; if(_highquality) { graphics.setrenderinghint(renderinghints.key_antialiasing, renderinghints.value_antialias_on); } if(shadowed) { graphics.setcolor(shadowcolora); graphics.fillroundrect(_shadowoffset, _shadowoffset, width - strokesize - _shadowoffset, height - strokesize - _shadowoffset, _arcs.width, _arcs.height); } else { _shadowgap = 1; } roundrectangle2d.float rr = new roundrectangle2d.float(0, 0, (width - shadowgap), (height - shadowgap), _arcs.width, _arcs.height); shape clipshape = graphics.getclip(); if(image == null) { graphics.setcolor(_backgroundcolor); graphics.fill(rr); } else { roundrectangle2d.float rr2 = new roundrectangle2d.float(0, 0, (width - strokesize - shadowgap), (height - strokesize - shadowgap), _arcs.width, _arcs.height); graphics.setclip(rr2); graphics.drawimage(this.image, 0, 0, null); graphics.setclip(clipshape); } graphics.setcolor(getforeground()); graphics.setstroke(new basicstroke(strokesize)); graphics.draw(rr); graphics.setstroke(new basicstroke()); } }
thanks help.
try "clipping area" (see g.setclip()
call):
public static void main(string[] args) { jframe f = new jframe(); f.setsize(new dimension(600, 400)); f.getcontentpane().setlayout(null); roundpanel rp = new roundpanel(); rp.setbounds(100, 50, 400, 300); f.getcontentpane().add(rp); f.setvisible(true); } static class roundpanel extends jpanel { @override protected void paintcomponent(graphics g) { // prepare red rectangle bufferedimage bi = new bufferedimage(400, 300, bufferedimage.type_int_argb); graphics2d gb = bi.creategraphics(); gb.setpaint(color.red); gb.fillrect(0, 0, 400, 300); gb.dispose(); // set rounded clipping region: roundrectangle2d r = new roundrectangle2d.float(0, 0, 400, 300, 20, 20); g.setclip(r); // draw rectangle (and see whether has round corners) g.drawimage(bi, 0, 0, null); } }
beware of restrictions mentioned in api doc graphics.setclip
:
sets current clipping area arbitrary clip shape. not objects implement shape interface can used set clip. shape objects guaranteed supported shape objects obtained via getclip method , via rectangle objects.
Comments
Post a Comment