`
微Smile
  • 浏览: 33023 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

画图板开发第一阶段感悟

    博客分类:
  • java
 
阅读更多

  到今天为止,我的第一个java开发的小项目——画图板终于可以算是出来了。都记不清楚做了有多久了,只清晰的记得一开始以为挺简单的,哪个该怎样怎样做好像有那么个大体思路,但等真动起手来才发现有那么多问题根本就不清楚。先不说细节,就是整体的逻辑思想也并未形成,只是实现一个算一个。所以仅从这点就收获经验,逻辑思路最重要,在未搞清楚整体思路前不能急于动手。
    不过,怎么说勉强还算完成了,最终结果如下:



    
    下面就来具体说说这看起来小小的画图板的实现吧,对于尚处于菜鸟之菜鸟的我,还真不简单啊。
      首先,它实现的功能有 1 画几种形状:曲线(为默认)、直线、矩形、多边行、椭圆、圆角矩形这几种;2 最挫的橡皮擦功能(你看到的断断续续的就是被擦掉的, );3 重绘功能(即画板最小化后重新显示所画的形状会被重新显示)。
      也就这几种了,至于这上面的菜单、形状按钮、颜色按钮等都是用各种布局管理器个加上去的,这个后面再说。先说说每个实现的功能的关键点吧。
      最简单的,画直线和矩形:
     
shape = new DrawLine(x1, y1, x2, y2, color);

      此处,DrawLine是一个继承了shape这个抽象类的画直线的类,类中调用了Graphics中的drawLine()方法。
       矩形:
      
shape = new DrawRect(x1, y1, x2, y2, Color.orange);
同理,在此类中调用drawRect(x,y,weight,height)方法。
        注意:此方法中(x,y)是指矩形左上角的坐标。关键:x可设置为Math.min(x1,x2),y可设置为Math.min(y1,y2),这样就可以画任意方向的矩形。
        曲线:
        首先,曲线可以看做是无数条直线所组成的,只要把起始坐标和下一个坐标交换即可。看代码:
// 默认为画曲线,即默认为铅笔
	public void mouseDragged(MouseEvent e) {
		//前者为曲线,后者为橡皮擦
		if (command == "images/draw6.jpg" || command == "images/draw2.jpg") {
			System.out.println("鼠标拖动");
			x2 = e.getX();
			y2 = e.getY();
			System.out.println("默认为画曲线");
			if(command == "images/draw6.jpg") {
				shape = new DrawLine(x1, y1, x2, y2, color);
			} else {
				shape = new DrawLine(x1,y1,x2,y2,Color.white);
			}
			x1 = x2;
			y1 = y2;
			shape.draw(g);//画曲线
			shapes.add(shape);//保存曲线到shapes队列中
		}

	}

       别看这段代码这么短,可没少费我时间 后来发现是在画布上加了MouseActionListener的监听器,却没有加MouseMontionListener这个控制鼠标拖动的监听器,要知道mouseDragged()这个方法是在MouseMontionListener中才有滴。真汗!附:后面的那个else就是实现那最挫的橡皮擦的,你会发现,都是在鼠标拖动时绘制直线,只是把颜色设置为白色。只要再把绘制的直线加粗就可以得到橡皮擦的效果,此还有待笔者研究,期待牛人指点! 呵呵
         多边形的绘制和曲线差不多,得注意的地方是得在鼠标释放后恢复现场。看代码:
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下");
		x1 = e.getX();
		y1 = e.getY();
		//画多边形时保存点击第一下时的位置
		if(command == "images/draw13.jpg" && flag == 0) {
			x0 = x1;
			y0 = y1;
			x3 = x1;
			y3 = y1;
			flag ++;
		}
}
 public void mouseClicked(MouseEvent e) {
		 System.out.println("被点击");
		 System.out.println(e.getX()+ " " + e.getY());
		 if( command == "images/draw13.jpg" && e.getClickCount() ==2 ) {
			 shape = new DrawLine(x0,y0,x3,y3,color.green);
			 shape.draw(g);
			 shapes.add(shape);//保存到内存
			 flag =0;//恢复现场
		 }
	 }

注意:读者可以试试没有flag==0这句的后果,我想说的就很明显了。

      实现的功能就是这些,再说说那仿xp画板的界面。其实就是几个JPanel容器堆积木似地堆出来的。拿左边的形状工具栏而言,把每个加有图片的按钮加到一个JPanel中,把这个JPanel加到JToolBar这个工具栏中,工具栏加到整个JFrame的西边,大体轮廓就出来了。再用setBorder()等设置一下组件的边界,那酷似原版的颜色工具栏就完成了。
      需要注意的是,有的组件得设置为透明,如下:
JPanel ColCheck = new JPanel(new GridLayout(2, 12));
for (int i = 0; i < 24; i++) {
			JLabel jl = new JLabel();// 循环得到16个标签
			jl.setBorder(new BevelBorder(BevelBorder.LOWERED, Color.white,
					Color.gray));
			jl.setOpaque(true);//设置组件透明
			jl.setBackground(ColGroup[i]);// 设置标签颜色
			jl.setPreferredSize(new Dimension(15, 15));// 设置按钮的大小
			
			ColCheck.add(jl);
		
		}

这是未设置透明时的效果:

     
      到此为止,这是全部已经实现的功能,但是此结果却离我想要达到的效果还有一定距离,比如面板不能缩放、颜色还不能选取、不能画不同粗细的线条等,都尚待完善。在此,再次像各位牛人请教哈。

      最后附录一些开发这次项目(算是个项目吧,虽然小)的其他技术方面的感悟或注意点:
       1 必须在setVisible(true)之后得到画布,在之前添加组件,否则有可能组件显示不出来,貌似曾经遇到过此情况。
        2 系统自动调用的paint(Graphics g)方法中的画布参数是从JFrame上面得到滴,若自己从别的JPanel jp上面得到画布则需注意得把它赋给JFrame上的画布,即this.g = jp.getGraphics();再传参。
        3 在按钮组ButtonGroup中加JButton得不到谁选中了,只有加JRadioButton才能得到它的选中命令,并且JRadioButton默认为未被选中,当鼠标点击一下按钮时,状态改变。
        注意:用到JRadioButton时还得设置一个按钮组ButtonGroup(在awt包中),才能保证单选。
       4  要自己定义组件的大小和位置时,得设布局管理器为null,用setbround(),传四个参数
       5 最重要滴,在代码设计上,一般得把监听器类和主类分开,注意构造函数的传参使用。这次在这点上久摔了大跟头,导致整个的代码看上去凌乱无章,耗费了大量时间。
       6 经常性的打印结果,对调试代码有好处。     
  • 大小: 48.7 KB
  • 大小: 24.5 KB
4
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics