到今天为止,我的第一个java开发的小项目——画图板终于可以算是出来了。都记不清楚做了有多久了,只清晰的记得一开始以为挺简单的,哪个该怎样怎样做好像有那么个大体思路,但等真动起手来才发现有那么多问题根本就不清楚。先不说细节,就是整体的逻辑思想也并未形成,只是实现一个算一个。所以仅从这点就收获经验,逻辑思路最重要,在未搞清楚整体思路前不能急于动手。
不过,怎么说勉强还算完成了,最终结果如下:
[img]http://dl.iteye.com/upload/attachment/575037/8f243ea5-e7d3-353e-9dfd-d1be7e282471.jpg[/img]
下面就来具体说说这看起来小小的画图板的实现吧,对于尚处于菜鸟之菜鸟的我,还真不简单啊。
首先,它实现的功能有 1 画几种形状:曲线(为默认)、直线、矩形、多边行、椭圆、圆角矩形这几种;2 最挫的橡皮擦功能(你看到的断断续续的就是被擦掉的, :oops: );3 重绘功能(即画板最小化后重新显示所画的形状会被重新显示)。
也就这几种了,至于这上面的菜单、形状按钮、颜色按钮等都是用各种布局管理器个加上去的,这个后面再说。先说说每个实现的功能的关键点吧。
最简单的,画直线和矩形:
此处,DrawLine是一个继承了shape这个抽象类的画直线的类,类中调用了Graphics中的drawLine()方法。
矩形:
注意:此方法中(x,y)是指矩形左上角的坐标。关键:x可设置为Math.min(x1,x2),y可设置为Math.min(y1,y2),这样就可以画任意方向的矩形。
曲线:
首先,曲线可以看做是无数条直线所组成的,只要把起始坐标和下一个坐标交换即可。看代码:
别看这段代码这么短,可没少费我时间 :cry: 后来发现是在画布上加了MouseActionListener的监听器,却没有加MouseMontionListener这个控制鼠标拖动的监听器,[color=red]要知道mouseDragged()这个方法是在MouseMontionListener中才有滴[/color]。真汗!附:后面的那个else就是实现那最挫的橡皮擦的,你会发现,都是在鼠标拖动时绘制直线,只是把颜色设置为白色。只要再把绘制的直线加粗就可以得到橡皮擦的效果,此还有待笔者研究,期待牛人指点! 呵呵 :)
多边形的绘制和曲线差不多,得注意的地方是得在鼠标释放后恢复现场。看代码:
注意:读者可以试试没有flag==0这句的后果,我想说的就很明显了。
实现的功能就是这些,再说说那仿xp画板的界面。其实就是几个JPanel容器堆积木似地堆出来的。拿左边的形状工具栏而言,把每个加有图片的按钮加到一个JPanel中,把这个JPanel加到JToolBar这个工具栏中,工具栏加到整个JFrame的西边,大体轮廓就出来了。再用setBorder()等设置一下组件的边界,那酷似原版的颜色工具栏就完成了。
需要注意的是,有的组件得设置为透明,如下:
这是未设置透明时的效果:
[img]http://dl.iteye.com/upload/attachment/575045/d2a03b7d-7e0b-34b2-9f1c-848b86ef2dad.jpg[/img]
到此为止,这是全部已经实现的功能,但是此结果却离我想要达到的效果还有一定距离,比如面板不能缩放、颜色还不能选取、不能画不同粗细的线条等,都尚待完善。在此,再次像各位牛人请教哈。 :D
最后附录一些开发这次项目(算是个项目吧,虽然小)的其他技术方面的感悟或注意点:
1 [color=yellow]必须在setVisible(true)之后得到画布[/color],在之前添加组件,否则有可能组件显示不出来,貌似曾经遇到过此情况。
2 系统自动调用的paint(Graphics g)方法中的画布参数是从JFrame上面得到滴,若自己从别的JPanel jp上面得到画布则需注意得把它赋给JFrame上的画布,即this.g = jp.getGraphics();再传参。
3 在按钮组ButtonGroup中加JButton得不到谁选中了,只有加JRadioButton才能得到它的选中命令,并且JRadioButton默认为未被选中,当鼠标点击一下按钮时,状态改变。
[color=red] 注意[/color]:用到JRadioButton时还得设置一个按钮组ButtonGroup(在awt包中),才能保证单选。
4 要自己定义组件的大小和位置时,得设布局管理器为null,用setbround(),传四个参数
5 [color=red]最重要滴[/color],在代码设计上,一般得把监听器类和主类分开,注意构造函数的传参使用。这次在这点上久摔了大跟头,导致整个的代码看上去凌乱无章,耗费了大量时间。
6 [color=orange]经常性的打印结果,对调试代码有好处。[/color]
不过,怎么说勉强还算完成了,最终结果如下:
[img]http://dl.iteye.com/upload/attachment/575037/8f243ea5-e7d3-353e-9dfd-d1be7e282471.jpg[/img]
下面就来具体说说这看起来小小的画图板的实现吧,对于尚处于菜鸟之菜鸟的我,还真不简单啊。
首先,它实现的功能有 1 画几种形状:曲线(为默认)、直线、矩形、多边行、椭圆、圆角矩形这几种;2 最挫的橡皮擦功能(你看到的断断续续的就是被擦掉的, :oops: );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队列中
}
}
别看这段代码这么短,可没少费我时间 :cry: 后来发现是在画布上加了MouseActionListener的监听器,却没有加MouseMontionListener这个控制鼠标拖动的监听器,[color=red]要知道mouseDragged()这个方法是在MouseMontionListener中才有滴[/color]。真汗!附:后面的那个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);
}
这是未设置透明时的效果:
[img]http://dl.iteye.com/upload/attachment/575045/d2a03b7d-7e0b-34b2-9f1c-848b86ef2dad.jpg[/img]
到此为止,这是全部已经实现的功能,但是此结果却离我想要达到的效果还有一定距离,比如面板不能缩放、颜色还不能选取、不能画不同粗细的线条等,都尚待完善。在此,再次像各位牛人请教哈。 :D
最后附录一些开发这次项目(算是个项目吧,虽然小)的其他技术方面的感悟或注意点:
1 [color=yellow]必须在setVisible(true)之后得到画布[/color],在之前添加组件,否则有可能组件显示不出来,貌似曾经遇到过此情况。
2 系统自动调用的paint(Graphics g)方法中的画布参数是从JFrame上面得到滴,若自己从别的JPanel jp上面得到画布则需注意得把它赋给JFrame上的画布,即this.g = jp.getGraphics();再传参。
3 在按钮组ButtonGroup中加JButton得不到谁选中了,只有加JRadioButton才能得到它的选中命令,并且JRadioButton默认为未被选中,当鼠标点击一下按钮时,状态改变。
[color=red] 注意[/color]:用到JRadioButton时还得设置一个按钮组ButtonGroup(在awt包中),才能保证单选。
4 要自己定义组件的大小和位置时,得设布局管理器为null,用setbround(),传四个参数
5 [color=red]最重要滴[/color],在代码设计上,一般得把监听器类和主类分开,注意构造函数的传参使用。这次在这点上久摔了大跟头,导致整个的代码看上去凌乱无章,耗费了大量时间。
6 [color=orange]经常性的打印结果,对调试代码有好处。[/color]