前面我们已经实现画板的一部分功能,今天我们接着来实现画板的另一部分的功能。
一、画板所要实现的功能
1.让用户能够选择图形,根据所选的图形来作图;
2.实现画直线、矩形、椭圆、圆角矩形、填充3D矩形、图片、等腰三角形
3.实现画曲线、刷子、橡皮、虚线、喷枪
前面我们已经实现了功能一和二,我们接着来实现功能三
二、需要用到的API类
javax.swing.JFrame 窗体类
java.awt.FlowLayout 流式布局类,设置窗体的布局类型,防止组件出现覆盖的现象
javax.swing.JButton 按钮元素组件类,可以添加按钮到画板上
java.awt.Dimension 设置组件大小的类,前面我们在实现登录界面的时候说过setSize方法只对顶层容器有效。如果要设置组件大小需要借助Dimension类
java.awt.MouseEvent 储存事件源对象的信息和动作信息的类
java.awt.event.MouseListener 鼠标事件接口,提供处理按下,释放,点击,进入和离开的动作
java.awt.Graphics 画笔类,提供绘制各种图形的方法
新增的API类
java.awt.event.MouseMotionListener 鼠标拖动的监听事件接口
java.awt.Graphics2D 设置画笔的属性
java.awt.BasicStroke 设置画笔的实线虚线java.util.Random 随机函数类
四、思路分析
大体思路与前一篇博客是一样。我们这里主要就是需要再多增一个MouseMotionListener接口。
五、代码分析
//定义画板类DrawFrame
import javax.swing.JFrame;
import java.awt.Graphics;
import javax.swing.JButton;
import java.awt.Dimension;
import java.awt.FlowLayout;
//实现一个画板类继承窗体类
public class DrawFrame extends JFrame{
//创建一个入口
public static void main(String args[]) {
DrawFrame jf=new DrawFrame();//实例化一个对象
jf.initFrame();
}
//创建一个创建窗体的方法
public void initFrame() {
this.setTitle("画板");
this.setSize(800, 600);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.setResizable(false);
//设置流式布局
FlowLayout fl = new FlowLayout(FlowLayout.CENTER,0,0);
this.setLayout(fl);
//设置大小
Dimension buttonsize=new Dimension(100,30);
//实例化一个画板监听类的对象
DrawListener dl = new DrawListener();
//设置一个不同选择的字符串
String[] name= {"直线","矩形","圆","圆角矩形","填充3D矩形","图片","等腰三角形","曲线","刷子","橡皮","喷枪","虚线","实线"};
//设置一个JButton对象数组
JButton but[]=new JButton[13];
//通过for循环来添加按钮组件
for(int i=0;i
//利用鼠标监听接口实现按钮监听类ButtonListener
import java.awt.event.MouseListener;
//实现MouseListener的接口
public class ButtonListener implements MouseListener {
private DrawListener dl;
public int num;//按钮编号
//获取当前画板监听对象
public ButtonListener(DrawListener dl,int num) {
this.dl = dl;
this.num=num;
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)
//当按钮被点击时,把传过来的按钮编号传给当前画板监听对象
public void mouseClicked(java.awt.event.MouseEvent e) {
//画线
dl.choose=num;
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mousePressed(java.awt.event.MouseEvent e) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseReleased(java.awt.event.MouseEvent e) {
};
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseEntered(java.awt.event.MouseEvent e) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseExited(java.awt.event.MouseEvent e) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseDragged(java.awt.event.MouseEvent arg0) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseMoved(java.awt.event.MouseEvent arg0) {
}
}
//利用鼠标监听接口实现画板监听类DrawListener
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.event.MouseMotionListener;
import java.awt.Graphics2D;
import java.util.Random;
//实现MouseListener的接口
public class DrawListener implements MouseListener,MouseMotionListener{
public int x1,y1,x2,y2;//获取鼠标按下和释放的坐标
private Graphics2D g;//定义一个画笔属性,然后去获取窗体的画笔
public int choose=0;
Random r = new Random();
public DrawListener() {
}
public void setGraphics(Graphics g) {
this.g=(Graphics2D)g;
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)
public void mouseClicked(java.awt.event.MouseEvent e) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mousePressed(java.awt.event.MouseEvent e) {
x1 = e.getX();
y1 = e.getY();
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseReleased(java.awt.event.MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
g.setColor(Color.black);
//当释放鼠标的时候画出实线,这里要利用到Graphics(画笔),窗体本身就包含一个画笔
//获取画笔后开始画
//画直线
if(choose==1) g.drawLine(x1, y1, x2, y2);
//画矩形
else if(choose==2) {
g.drawRect(Math.min(x1, x2),Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
}
//画椭圆
else if(choose==3) {
g.drawOval(Math.min(x1, x2),Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
}
//画圆角矩形
else if(choose==4) {
g.drawRoundRect(Math.min(x1, x2),Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2), 10, 10);
}
//填充矩形
else if(choose==5) {
g.fillRect(Math.min(x1, x2),Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
}
//添加图片
else if(choose==6) {
Image icon= new ImageIcon("C:\\Desktop\\蓝杰学习\\材料\\爱晚亭.gif").getImage(); //这里不能用ImageIcon
g.drawImage(icon, Math.min(x1, x2),Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2), null);
}
//画一个等腰三角形,需要三条线
else if(choose==7) {
//起点是等腰三角形的顶点
if((y1x2)&&(y1y2)&&(x1>x2)) {
g.drawLine(x1, y1, x1-(y1-y2), y2);
g.drawLine(x1, y1, x1+(y1-y2), y2);
g.drawLine(x1-(y1-y2), y2, x1+(y1-y2), y2);
}
else if((x1y2)) {
g.drawLine(x1, y1, x2, y1-(x2-x1));
g.drawLine(x1, y1, x2, y1+(x2-x1));
g.drawLine(x2,y1-(x2-x1),x2,y1+(x2-x1));
}
}
};
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseEntered(java.awt.event.MouseEvent e) {
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseExited(java.awt.event.MouseEvent e) {
}
//这里我们要用到是鼠标的拖动,在拖动的过程中画出线
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseDragged(java.awt.event.MouseEvent e) {
g.setColor(Color.black);
//画曲线
if(choose==8) {
x2=e.getX();
y2=e.getY();
//通过把drawLine来画
g.drawLine(x1, y1, x2, y2);
//在拖动的过程中必须不断地将终点设置为下一个drawLine的七点,这样才能够连起来
x1=x2;
y1=y2;
}
//刷子只要把画笔的宽度增加就可以了
else if(choose==9) {
x2=e.getX();
y2=e.getY();
g.setStroke(new BasicStroke(10));//不可以直接设置大小
g.drawLine(x1, y1, x2, y2);
x1=x2;
y1=y2;
}
//橡皮的话需要把画笔的宽度增大,并把颜色设置为白色
else if(choose==10) {
x2=e.getX();
y2=e.getY();
g.setStroke(new BasicStroke(40));//不可以直接设置大小
g.setColor(Color.white);//设置为白色
g.drawLine(x1, y1, x2, y2);
x1=x2;
y1=y2;
}
//喷枪则需要借助随机函数来实现
else if(choose==11) {
g.drawLine(x2, y2, x2, y2);
for (int i = 0; i < 10; i++) {
int p = r.nextInt(10);
int q = r.nextInt(10);
g.drawLine(x2 + p, y2 + q, x2 + p, y2 + q);
}
}
//设置虚线
else if(choose==12) {
float[] dash={5,5};
BasicStroke bs1 = new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER, 10.0f,dash,0.0f);
g.setStroke(bs1);
x2=e.getX();
y2=e.getY();
g.drawLine(x1, y1, x2, y2);
x1=x2;
y1=y2;
}
//设置实线
else if(choose==13) {
BasicStroke bs2 = new BasicStroke(1);
//没怎么懂。。。
g.setStroke(bs2);
x2=e.getX();
y2=e.getY();
g.drawLine(x1, y1, x2, y2);
x1=x2;
y1=y2;
}
}
// Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
public void mouseMoved(java.awt.event.MouseEvent e) {
}
}
六、总结
1.这里由于我们需要对画笔的属性进行设置,所以我们需要把Graphics 的对象强制转化为Graphics2D
2.setStroke(new BasicStroke(10))。setStroke方法里面的参数是BasicStroke对象,而不是数值。不能直接传值
3.我们在使用刷子的时候把画笔的颜色设置成了白色,那么我们在使用完刷子再去使用其他图形时就会出现其他图形的线条也会变成了白色。因此我们需要在所有的方法前加一个颜色设置g.setColor(Color.black);
七、实现后的界面