swing - Java create a brush stroke action -
when draw freehand line paint application whatever brush ends stacking multiple points of brush form brush stroke.
for example basic pen stroke stack 1 pixel drag mouse. in more advanced applications have brush fancy shape, say: star example, , stroking canvas "star brush" cause paint application draw multiple stars drag mouse on canvas. please correct me if i'm wrong.
i have implemented "brush" ( i.e. basic circle ) , whenever user drags mouse on canvas while holding left-mouse-button application draws circle each new mouse position.
my problem "undo feature" if may call way.
when undo action, application deletes last shape ( circle ) drawn, while want delete whole free-hand drawing ( collection of shapes / circles ) user first press of left-mouse-button release.
how "pack" collection shape objects 1 ? problem repainting of circles, want repainting of maybe 30000 circles fast, bufferedimage.
i use bufferedimage background of image.
every shape "older" 50 gets permanently stored in bufferedimage background.
currently store last 50 shape objects in arraylist , 51st ( oldest ) gets permanently stored in bufferedimage. user can't undo 50 actions rather 50 shapes.
thank you!
stripped down code sample:
public class graphicpanel extends jcomponent{ private int x = 0; private int y = 0; private int compxlen = 100; private int compylen = 100; private boolean iscompfilled = false; private boolean isareatobepainted = false; private boolean isfocused = false; private shape ghost; private arraylist<shape> shapebuffer = new arraylist<shape>(); private bufferedimage img = new bufferedimage( pref_w, pref_h, bufferedimage.type_int_argb ); private static final int pref_w = 800; private static final int pref_h = 500; @override public void paintcomponent( graphics gplain ){ super.repaint(); graphics2d g = (graphics2d)gplain; //paint background if (img != null){ g.drawimage(img, 0, 0, null); } ghost = new ellipse2d.double( x-( compxlen/2 ), y-( compylen/2 ), compxlen, compylen ); if( isareatobepainted ){ //add ghost shape arraylist add( g, ghost ) } //paint arraylist for( shape s : shapebuffer ){ g.fill( s ); } if( isfocused ){ // draw ghost shape g.draw( ghost ); } } /** * adds circles arraylist */ private void add( graphics2d g, shape s ){ //fetch last arraylist element in shape shp //add ghost shape @ top of arraylist graphics2d g2 = img.creategraphics(); shapebuffer.add( shp ); g2.fill( shp ); g2.dispose(); } public void cleararea(){ shapebuffer = new arraylist<shape>(); img = new bufferedimage( pref_w, pref_h, bufferedimage.type_int_argb ); repaint(); } private class graphicpanelmouselisten implements mouselistener, mousemotionlistener{ /** * @param e mouse event * @since 0.1 */ @override public void mouseclicked( mouseevent e ){} public void mousepressed( mouseevent e ){ x = e.getx(); y = e.gety(); isareatobepainted = true; repaint(); } public void mousereleased( mouseevent e ){} public void mouseentered( mouseevent e ){ isfocused = true; } public void mouseexited( mouseevent e ){ isfocused = false; repaint(); } public void mousedragged( mouseevent e ){ isareatobepainted = true; x = e.getx(); y = e.gety(); repaint(); } public void mousemoved( mouseevent e ){ x = e.getx(); y = e.gety(); repaint(); } }//public class graphicpanelmouselisten implements mouselistener }//public class graphicpanel
you can avoid using these lists altogether storing every finished brush stroke, or action matter, in own image. can layer these in order made. fewer of them, can define how many actions in past want have while bottom 1 containing didn't fit in history.
pixel blit relatively fast operation, unlike stuff shapes, , can make faster using volatileimage instead of buffered image collecting actions in history.
in opinion approach faster, , less restricting actions added in future. can mark layers invisible , move , forth through history in photoshop instance, without dependency on actual contents of said layers.
Comments
Post a Comment