随意所想(关于画图板)

从刚刚接触java到此已有一个月的时间了。从刚刚开始的一窍不通到现在也算是已经初窥门路,不仅有一番自己的感想为此,写下此文,一为表达一下如今的想法,二也为将来回头怀旧之时能有一番独特的回忆吧。

        说实话,步入蓝杰,起初只是为了消磨时光,不让自己这个大学生活白白消逝掉而已。因为大一过得太过平静,总觉这样太过平庸了。所以急切的想让自己有一个能为之努力地目标。所以,我来到了蓝杰。我其实并不认为我是一个能学好编程的人。因为做事我比较急躁,经常出错。往往对自己的行为无法很好地控制,没有足够的耐心。这些缺点恰恰是程序员所深恶痛绝的。但是,我却依然选择了这个方向,着实因为我喜欢那种自己动手做好一件事的成就感,看着自己动手编写的程式在电脑上运行,总用一种莫名的喜悦萦绕在心头,让我坚持的把它完成下去。渐渐地,我便完成了一个有一个的“任务”,也渐渐地开始喜欢上了编程。那么,让我们归入正题,毕竟这篇博文叫做画图板制作总结,总要回归到我们的画图板上面。

        画图板,是我进入蓝杰所做的第一个像样的程序,对于大神们当然是小菜一碟,但是对于我们这些这辈子还没写过几行代码的人确实一个跨越式的挑战。刚刚听到这个问题,感到很无力,也是因为不了解java,很怀疑用哪种字母拼写而出的代码是怎样讲一个实体化的画图程序完成的。但是随着几节课的慢慢了解,和对java的熟悉。也渐渐的摸清了门路。开始了对画图程序的一点点的完成。1.首先是基本框架,这个很简单只需要按照书中的方法加上老师的讲解很容易就完成了。一个JFrame当做程序的主体,几个JToolBar当做工具栏和颜色栏就可以完成。然后再把想要的按钮一个个的加在相应的面板上就可以初步完成一个画图板的框架。这些都是很浅显易懂的问题,只需要看看书就可以轻松解决。至于美化问题则以后再说。        2.按钮程序的编写。这才是比较困难的地方,首先最先要了解什么是监听器,首先要搞懂监听器的用法。否则就算写出了代码也不能理解。按我的想法,监听器就是一个“方法”,而方法名就是这个按钮,只要使用了按钮就相当于使用了这个方法,不同的监听器对于不同的操作有不同的反馈,总之万变不离其宗。因为上个学期我自学过一段时间delphi的编写,为了应付该死的课程设计,但也有所收获。那就是对于面向对象的理解。delphi是纯图像化的,做程序要相对于java简单些,哪里给相应按钮编写代码,只需要在相应的按钮上点击即可。而java虽然复杂一些,但其实也是很类似的,只不过java把按钮和其代码分居两地,再用所谓监听器连接起来而已。这样理解下来,我就基本上能够熟练的使用监听器了。在此,不得不提一下,在监听器的使用中的一个重要问题,那就是对象的传递,众所周知,java为面向对象的语言,没有对象就没办法使用方法,所以对象的传递是十分重要的。一般情况下,我喜欢把监听器程序独立建立一个类,这样更加规整。除非是那种很短的监听器编写,才会直接一个内部类解决掉。这样就要通过构造方法将原来类中的对象转移过来,才能靠监听器类调用原来类中相应的方法。这样才能实现相应的功能。       3.画线的实现,正所谓画图板,画图才会最主要的功能。还好,java中已经给我提供了相应的画图方法,不用自己亲自编写可算是谢天谢地,但是有些画图功能还是很不完善。比如多边形的制作并没有给出,只能靠自己手动制作了,为了使自己的多边形跟xp中的画图板类似,所以用到了三个监听器来实现,鼠标点击、鼠标按下和鼠标释放。按下和释放在画直线矩形中已经很熟悉了,用起来也比较容易了。但是这个鼠标点击监听器却出了麻烦,因为鼠标点击即为按下和释放在同一个点进行,在点击过后同时会将三个监听器中的代码全部运行一遍,要做好多边形就要将起始点和最后一个点连接起来,势必就要将起始点记录下来。可是因为其实点记录是在释放监听器中记录的,所以,每一次点击事件也会进行一次释放程序,这样刚刚记录的起始点的坐标就又被覆盖掉了,所以要控制在点击事件中不进行释放事件的运行。最后想到设置一个变量,通过在运行不同程序是改变它的数值,最后通过判断变量的数值来确定此时要运行什么监听器。这种方法在以后的画图板编程中,又有数次使用,很是好用,这次可以算是我的一次重要的突破。int a=0,b=0;

if(t.getAction().equals("Polygon")){  		
    		//g2d.setStroke(new BasicStroke(f22.getaSize()));
    		sh=new Line(x1, y1, x2, y2,f22.getaSize(),c.getColor());
    		if(a==0){
    			x4=x2;
    			y4=y2;
    		}
    		a=1;
    		sh.drawShape((Graphics2D)g);
        	dl.add(sh);
    	}
if(t.getAction().equals("Polygon")){
    		if(b==0){
    			x5=x1;
    			y5=y1;
    		}
    		b=1;
    	} 

 还有一个小问题是,就是在是自己的代码可以正确绘制矩形和椭圆等,开始进行了一个一个的判断大小来找到两个坐标的最小值,后来才知道有一个Math.min()函数,浪费了很多时间,所以今后要尽量留意java的封装方法,免得以后多费工夫。曲线的绘制则要有数学上的知识,我是使用贝塞尔曲线来制作的曲线,首先画出四个点,将其连接起来,即完成三条直线,然后用贝塞尔曲线公式x=(1-t)*(1-t)*(1-t)*x1+3*t*(1-t)*(1-t)*x2+3*t*t*(1-t)*x3+t*t*t*x4;y=(1-t)*(1-t)*(1-t)*y1+3*t*(1-t)*(1-t)*y2+3*t*t*(1-t)*y3+t*t*t*y4;来确定曲线上的点,通过t的增加循环来画出曲线。并且要在循环结束后,消除掉原来所画的三条直线。(我是使用对列重绘的方法,使其三条线不保存在队列中,然后刷新面板即可)public void drawShape(Graphics2D g) {

			g.setColor(color);
			g.setStroke(new BasicStroke(size));
			double x,y;
			for(double t=0;t<=1;t=t+0.001){
				x=(1-t)*(1-t)*(1-t)*x1+3*t*(1-t)*(1-t)*x2+3*t*t*(1-t)*x3+t*t*t*x4;
				y=(1-t)*(1-t)*(1-t)*y1+3*t*(1-t)*(1-t)*y2+3*t*t*(1-t)*y3+t*t*t*y4;
				g.drawLine((int)x,(int)y, (int)x, (int)y);
			}
		}

  喷枪的制作则是需要随机数的帮忙,在鼠标经过的坐标的周围随即画出数十个点即可完成喷枪,比较简单,此处不再赘述。        4.重绘的实现。这个是画图板比较关键的地方了,总共有三种方法,我比较喜欢用队列保存图形对象的方法,这种方法比较浪费内存空间,但是相对比较好操作图形,这样放大镜和撤销的操作会很简单。首先创建Shape抽象类,并且建立好画图的方法和属性。这样做是为了在对列中方便一起保存各个图形。(ps:既然说到了队列,在这里说一下队列的基本创作步骤,队列就是可以自动能加长度的数组,所以只要增加长度时,重新创建一个数组比原来的长一,并且放进原来数组的数据和新的数据就完成了队列的自动怎么增加长度了。)依次创建你想要画的图形类,并且继承Shape,在里面完成图形的绘制。这样就创建好了各个图形的类,这样在每次画好图形以后,就要把这些图形对象保存在队列中。最后在主窗体中,重写paint的方法,在其使用父类所有的方法之后(super),在把队列中所有的图形对象重新再画板中画出来。这样就完成了画图板的重绘工作。另外两种方法分别是截图画点和截图贴图的方法,主要是学会用robot类截图的使用,其实只要学会使用帮助文档,这些问题就可以迎刃而解。帮助文档是很强大的,又不会用的类就要多多查看,对学习java很有帮助。class Drawing extends JPanel{

		public void paint(java.awt.Graphics g){
			super.paint(g);
			for(int i=0;i<dl.getSize();i++){
				Shape sh = dl.search(i);
				java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
				sh.drawShape(g2);
			}
		}
	}

            5.写字板工具的实现。这个问题的难点在于文本框的制作与消失,要在文本框里写好文字,再点击后是文本框消失掉,并且在画板相应的位置写上相应的文字。经过一段时间的尝试,决定文本框用矩形图形来做,写字的用JTextField来做最为容易,并且做好变量,使其第一次点击事,画出文本框并可以写字,第二次点击时帮文本框去掉,并在相应位置上写好相应的字。绝对布局比较容易进行位置上的调整,而矩形的消失可以不加进队列中来完成消失,或者直接在队列中删除即可完成。 if(t.getAction().equals("Write")){

    		if(m==1){
    			sh=new Rect2(x1, y1, x2, y2,1,Color.black);
	    		sh.drawShape((Graphics2D)g);
	        	dl.add(sh);
	    		d.setLayout(null);
	    		jta=new JTextArea("请输入文字");
	    		d.add(jta);
	    		jta.setBounds(x1+2, y1+4, Math.max(Math.abs(x1-x2)-4,76), 21);	
	    		x6=x1+2;
	    		y6=y1+17;
	    		d.updateUI();
				m=0;
			}
    		else if(m==0){
    			str=jta.getText();
    			jta.setVisible(false);
    			dl.delete(dl.getSize()); 
    			sh=new Write(x6,y6, str,c.getColor());
	    		sh.drawShape((Graphics2D)g);
	        	dl.add(sh);
    			d.updateUI();
    			m=1;
    		}
    	}

     6.其他。例如取色笔,橡皮,刷子一类的东西都可以用一些简单的方法实现,没有什么难度,就不做记录了。          7.画图板的美化工作。美化部分我感觉最有用的地方就是边框的制作,用java的边框类可以很容易的给组建添加边框setBorder(new BevelBorder())这样可以使按钮变得美化的多,而且也可以用绝对布局来是组件重叠。绝对布局是很有用的,我在做一些按钮面板时,有些面板需要特定的情况才显示出来,但如果用其他布局就要站很大地方,并且可能挤掉原来哪些可见的面板,非常浪费空间。而是用绝对布局就可以使不可见的组件叠加起来,可以省下很大的空间。我的粗细面板和放大镜选项就是如此做的,这样可以随意显示我想要的面板。再给各个按钮加上相应的图标,做成跟xp画图板相似的按钮。

           现在我也算是完成了画图板的基本功能。看着自己完成的画图板,不禁有一种亲切感和自豪感。但是我也知道,现在的我还是远远不够的,只不过刚刚有了一点皮毛而已。但是,从这短短的时间里,我学习的不仅仅是一种编程语言,也学会了学习的方法。我认为无论学习什么,都要有良好的方法方式,这样在今后的学习中才能更快的进步。我没有什么报效国家的伟大理想,只是想在自己的大学生活中有一个充实的每一天。从现在来看这篇博客都不像是什么技术总结了,更像是我这段时间的一个生活志,无论是什么。我不想把它当做是一个为了交差而写的文章。我要给自己的未来创造一点点精彩的回忆,让这短短的几个字能在我今后回首时,留下一丝淡淡的微笑。既然做了,就不会后悔,这里算是给自己一个决心,我会努力去学下去。(ps:因为是第一次写,不想把这个写成一个简单的技术总结,想把在蓝杰过得这一个月的感觉说出来,都是随心所想的一些感想,更不想对所谓字数去纠结。就当一些胡言乱语吧,我个人比较随意,想到什么就写了什么,所以请那些不幸看到这篇文字的人见谅)

猜你喜欢

转载自liguanyi11111.iteye.com/blog/1474743