今天,重写了一下画图板,主要有两个方面:其一是实现画图板的圆角矩形、刷子、橡皮、铅笔、以及多边形的功能;其二是对原来的XP_Draw类进行拆分,把它分成十几个类,从而充分的体现了JAVA的面向对象的编程思想——“一切皆对象”。
对于画图板这几项功能,圆角矩形可以说是最简单的,只需要用到java.awt.Graphics类中drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight),其中arcWidth 是4 个角弧度的水平直径,arcHeight 是 4 个角弧度的垂直直径,width和height的值应该是绝对值,这就需要用到lang包中的math类的abs求绝对值的方法,而对于x,y应该是获取两个点坐标中较小的x,y的值,这就需要用到math类中的min方法。再就是铅笔功能的实现,这需要对鼠标移动事件进行侦听(MouseMotionListener接口),用到了mouseDragged方法,能够不断获取鼠标移动的坐标,然后就画直线,最后再交换坐标,重新获取。因为对于MouseMotionListener接口要重写里面所有的方法,这是非常没有必要的,所以我们用到MouseAdapter类,它其中包括了MouseListener(按下、释放、单击、进入或离开),MouseMotionListener,MouseWheelListener(鼠标滚轮事件)等,只需要我们创建MouseEvent侦听器,并对所需要的方法进行重写。刷子和橡皮的实现跟铅笔差不多,只不过橡皮是将颜色改成了白色,刷子要用到Graphics2D类,因为这个类中有setStroke方法可以设置图形属性(宽度),因为Graphics2D类扩展了Graphics类,所以要用到强制类型转换。对于多边形的功能可以说是最难的,首先,需要我们获取并保存鼠标第一次按下的点的坐标,然后获取鼠标释放的点的坐标,这样可以画出第一条直线,然后进行坐标交换。当然这里面要进行一些控制,具体代码如下:
mousePressed方法下:
x1 = e.getX();
y1 = e.getY();
if (cout == 0)
a = x1;
b = y1;
}
g.setColor(color);// 动态设置颜色
mouseReleased方法下:
case "polygon":
if (cout == 0) {
// 画第一条直线
g.drawLine(x1, y1, x2, y2);
x4 = x2;
y4 = y2;
cout++;
} else {
// 画第一条直线之后的直线
g.drawLine(x4, y4, x2, y2);
x4 = x2;
y4 = y2;
}
break;
mouseClicked方法下:
x3 = e.getX();
y3 = e.getY();
switch (command) {
case "polygon":
if (e.getClickCount() == 2) {
// 画直线(最后)
g.drawLine(a, b, x3, y3);
cout = 0;
break;
再有一个问题就是监听的问题,这里有三个方面的监听,其一是对画图面板上鼠标的监听(上文已解释),其二是对颜色的监听;其三是对形状的监听。对于监听,首先要创建监听对象,然后再添加监听器。对于颜色和形状的监听,用到是ActionListener类中的actionPerformed方法,但方法的具体实现却有所不同:在颜色监听的方法中:JButton button = (JButton) e.getSource();color = button.getBackground();;在形状监听的方法中,直接使用getActionCommand方法来获取字符串,但这样要在之前给按钮做标记(button.setActionCommand(shapes[i]);)。
对XP_Draw进行拆分,这需要拆成Color_Panel、Draw_Panel、Tool_Panel、MyMouseListener、Shape等一些工具类。拆分的重点就是对于参数的传递,这里涉及到是传对象还是传变量。如果是只需要传一次,我们可以传变量;但如果要传多次,只能通过传对象。同时,还用到了顶级抽象Shape,Line等是对抽象类的继承并对其抽象方法进行实现。
对于重绘,我们用到了paint方法,难点是对于数据的存储,这里我们只需要存储shape这个对象就行了。对于数据结构,我们用到了自定义的MyList类,具体实现如下:
package com.huaxin.version4;
/**
* 自定义队列 容器 保存形状对象的队列
*
*/
public class MyList {
//原始数组
private Shape[] srcArray = new Shape[0];
/**
* 在队列末尾添加一个元素
* @param element 要添加的元素
*/
public void add(Shape element){
//创建一个新的数组,长度比srcArray大1
Shape[] newArray = new Shape[srcArray.length+1];
//循环将原始数组中的所有的元素拷贝到新数组中
for(int i=0;i<srcArray.length;i++){
newArray[i] = srcArray[i];
}
//将要添加的元素element添加到新数组末尾
newArray[srcArray.length] = element;
//数组交换
srcArray = newArray;
}
/**
* 取出指定下标处的元素
* @param index 指定下标
* @return 元素
*/
public Shape get(int index){
return srcArray[index];
}
/**
* 返回队列的长度
* @return
*/
public int getLength(){
return srcArray.length;
}
}