简易绘图板
简易绘图板的实现,主要用到了java.awt和javax.swing包中的制作界面的相关知识,其次是Graphics类用于绘图,最后用监听器将两者联系起来。
监听器
监听器用于监听事件,比如:鼠标点击、键盘输入等等。他们被定义在java.awt.event这个包中。
安装监听器主要有三个步骤:
1、寻找事件源,即当前动作发生的组件。
2、建立事件处理类,将监听器的抽象方法完善。
3、将事件源和事件处理类绑定。
在简易绘图板中,我们主要用到了动作监听器和鼠标监听器。动作监听器用于监听鼠标点击和键盘输入空格等动作。鼠标监听器用于监听鼠标的动作,如:按下、释放、进入等等。
Graphics类
Graphics类是java.awt包下的,主要用于绘图。有绘制圆形、直线,调整画笔颜色等各种功能。
java.awt与javax.swing包
java.awt与javax.swing包中的一部分类用于基本界面的制作,而我们知道如果想要绘图必须要有窗体,因此我们需要掌握界面制作的基本知识,包括:窗体、按钮、布局、文本框等等。而这些组件都在java.awt或者javax.swing包下面。
简易绘图板实现
功能介绍
1、可以画出直线、圆、矩形、三角形、多边形。
2、可以选取不同的颜色。
3、可以显示画笔当前颜色。
4、可以保存画下的图形,不会因为拉伸窗口而消失。(通过每次打开再重新绘制一遍实现)
实现步骤
1、建立三个类:
DrawUI(用于绘图)
DrawListener(用于写事件监听器)
Shape(用于保存画下的图形)。
2、在DrawUI(事先继承JFrame窗体类)中创建窗体、事件监听器、Graphics的绘图范围获取、并将鼠标监听器和Graphics绘图范围相连。
this.setTitle("简易绘图板");
this.setSize(1000, 800);
this.setDefaultCloseOperation(3);
FlowLayout fl=new FlowLayout();
this.setLayout(fl);
DrawListener dl=new DrawListener();
this.setVisible(true);//开始在显卡下显示
//获取绘图板范围,注意传参的是Graphics而不是JFrame;
Graphics g=this.getGraphics();//一定要先让窗体显示,才可以获得它的图形,进而设置了绘图范围。
//给窗体加上鼠标监听器
this.addMouseListener(dl);
//让鼠标监听器活动的范围设置成画图的范围。
dl.g=g;
3、DrawListener类和MouseListener、ActionListener两个接口相连,同时完善相关抽象方法。
public class DrawListener implements MouseListener,ActionListener{
//用于存储图形很计数
Shape[] arrayShape=new Shape[100];
int countShape=0;
//绘图用到的坐标
int x1,x2,y1,y2,x3,y3,x4,y4,x5,y5;
//多边形用动态数组存储
int []x=new int[100];
int []y=new int[100];
int count_duobianxingX=0;
int count_duobianxingY=0;
//count用于三角形的三个坐标的计步
int count=0;
//画笔
Graphics g;
//按钮,此按钮用于显画笔当前颜色
JButton jbuc;
//str记录按钮上的文字,从而判断要求画的是哪种图形
String str="123";
//将DrawUI中的按钮传到DrawListener中
public void setJBu(JButton jbu)
{
jbuc=jbu;
}
//重写ActionListener的抽象方法
public void actionPerformed(ActionEvent e)
{
//如果按钮上没有字体,那么是改变颜色的按钮。
if(e.getActionCommand().equals(""))
{
JButton jb1= (JButton)e.getSource();
g.setColor(jb1.getBackground());
jbuc.setBackground(jb1.getBackground());
}
else
str=e.getActionCommand();
}
//重写MouseListener的抽象方法
public void mouseClicked(MouseEvent e)
{
if(str.equals("三角形"))
{
if(count==0)
{
x3=e.getX();
y3=e.getY();
g.drawOval(x3-4, y3-4, 8, 8);
count++;
}
else if(count==1)
{
x4=e.getX();
y4=e.getY();
g.drawOval(x4-4, y4-4, 8, 8);
g.drawLine(x3, y3, x4, y4);
count++;
}
else if(count==2)
{
x5=e.getX();
y5=e.getY();
g.drawOval(x5-4, y5-4, 8, 8);
g.drawLine(x3, y3, x5, y5);
g.drawLine(x4, y4, x5, y5);
//画完之后一定要立刻存储,下同。
arrayShape[countShape++]=new Shape(x3,x4,x5,y3,y4,y5,str,g.getColor());
count=0;
}
}
if(str.equals("多边形"))
{
if(e.getButton()==1)
{
x[count_duobianxingX++]=e.getX();
y[count_duobianxingY++]=e.getY();
g.drawOval(e.getX()-4 ,e.getY()-4, 8, 8);
if(count_duobianxingX!=1)
{
g.drawLine(e.getX(), e.getY(), x[count_duobianxingX-2], y[count_duobianxingY-2]);
}
}
//以右击鼠标代表多边形最后一个顶点
else if(e.getButton()==3)
{
x[count_duobianxingX++]=e.getX();
y[count_duobianxingY++]=e.getY();
g.drawOval(e.getX()-4 ,e.getY()-4, 8, 8);
g.drawLine(e.getX(), e.getY(), x[count_duobianxingX-2], y[count_duobianxingY-2]);
g.drawLine(x[0], y[0], e.getX(), e.getY());
arrayShape[countShape++]=new Shape(x,y,str,g.getColor(),count_duobianxingX);
count_duobianxingX=0;
count_duobianxingY=0;
}
}
}
public void mousePressed(MouseEvent e)
{
x1=e.getX();
y1=e.getY();
}
//直线、矩形、圆都是释放鼠标代表开始画
public void mouseReleased(MouseEvent e)
{
x2=e.getX();
y2=e.getY();
if(str.equals("直线"))
{
g.drawLine(x1, y1, x2, y2);
arrayShape[countShape++]=new Shape(x1,x2,y1,y2,str,g.getColor());
}
if(str.equals("矩形"))
{
g.drawRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
arrayShape[countShape++]=new Shape(x1,x2,y1,y2,str,g.getColor());
}
if(str.equals("圆"))
{
g.drawOval(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
arrayShape[countShape++]=new Shape(x1,x2,y1,y2,str,g.getColor());
}
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
4、在DrawUI中添加按钮,并将按钮和DrawListenr相连。
//三个添加按钮的重载函数
public JButton addButton(JFrame jf,DrawListener dl)
{
JButton jbu=new JButton();
jbu.setBackground(Color.BLACK);
jbu.setPreferredSize(new Dimension(30,100));
this.add(jbu);
jbu.addActionListener(dl);
return jbu;
}
public void addButton(String str,JFrame jf,DrawListener dl)
{
JButton jbu=new JButton(str);
this.add(jbu);
jbu.addActionListener(dl);
}
public void addButton(Color col,JFrame jf,DrawListener dl)
{
JButton jbu=new JButton();
jbu.setBackground(col);
jbu.setPreferredSize(new Dimension(30,30));//组件都要用Setpreferredsize来设置大小
this.add(jbu);
jbu.addActionListener(dl);
}
//图形选项按钮
String[] jbustr= {"直线","圆","矩形","三角形","多边形"};
for(int i=0;i<jbustr.length;i++)
{
addButton(jbustr[i],this,dl);
}
//将显示当前颜色的按钮传到监听器中,在监听器中改变它的颜色
JButton jbuc=addButton(this,dl);
dl.setJBu(jbuc);
// 颜色选项按钮
Color[] jbucol= {Color.black,Color.BLUE,Color.cyan,Color.darkGray,Color.green,Color.orange,Color.PINK,Color.red};
for(int i=0;i<jbucol.length;i++)
{
addButton(jbucol[i],this,dl);
}
5、完善Shape类。
public class Shape {
//存储图形需要的坐标
private int x1,x2,y1,y2,x3,y3,x4,y4,x5,y5;
//存储多边形需要的数组和计数
private int[] x=new int[100];
private int[] y=new int[100];
private int count_duobianxing;
//图形类型和颜色
private String name;
private Color col;
//通过构造函数重载实现保存不同的图形
public Shape(int x1,int x2,int y1,int y2,String name,Color col)
{
this.col=col;
this.name=name;
this.x1=x1;
this.y1=y1;
this.x2=x2;
this.y2=y2;
}
public Shape(int x1,int x2,int x3,int y1,int y2,int y3,String name,Color col)
{
this.col=col;
this.name=name;
this.x1=x1;
this.x2=x2;
this.x3=x3;
this.y1=y1;
this.y2=y2;
this.y3=y3;
}
public Shape(int[] x,int[] y,String name,Color col,int c)
{
this.col=col;
this.name=name;
System.arraycopy(x, 0, this.x, 0, c);
System.arraycopy(y, 0, this.y, 0, c);
this.count_duobianxing=c;
}
//注意绘图时参数时画笔g
public void Draw(Graphics g)
{
switch(this.name)
{
case("直线"):
{
g.setColor(col);
g.drawLine(x1, y1, x2, y2);
break;
}
case("矩形"):
{
g.setColor(col);
g.drawRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
break;
}
case("圆"):
{
g.setColor(col);
g.drawOval(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
break;
}
case("三角形"):
{
g.setColor(col);
g.drawOval(x1-4, y1-4, 8, 8);
g.drawOval(x2-4, y2-4, 8, 8);
g.drawOval(x3-4, y3-4, 8, 8);
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x3, y3);
g.drawLine(x1, y1, x3, y3);
}
case("多边形"):
{
g.setColor(col);
for(int i=0;i<count_duobianxing;i++)
{
g.drawOval(x[i]-4,y[i]-4,8,8);
if(i!=count_duobianxing-1)
g.drawLine(x[i], y[i], x[i+1], y[i+1]);
else
g.drawLine(x[0], y[0],x[count_duobianxing-1],y[count_duobianxing-1]);
}
}
}
}
}
6、在DrawUI中建立Shape数组,并将DrawListener中的Shape数组传过来,以便在每次窗体初始化调用paint函数时显示。
private Shape[] arrayShape=new Shape[100];
arrayShape=dl.arrayShape;
public void paint(Graphics g)
{
super.paint(g);
for(int i=0;i<this.arrayShape.length;i++)
{
arrayShape[i].Draw(g);
}
}