一、项目总体分析
[1]界面的实现:界面分为三块,工具块,画布块,以及颜色选择块。
[2]通过鼠标对界面控制的实现。
[3]画布图像的重绘,以是图像可以在此存在。
[4]画布图像的文件保存。
二、具体方法
[1]界面的实现:
主要运用Java中的JFrame组件,来实现界面的诸多功能。
重点方法有:
1、设置窗体的基本元素。
// 创建流体布局对象。 java.awt.FlowLayout f1 = new java.awt.FlowLayout();
// 设置流体布居。 this.setLayout(f1);
// 设置窗体的居中显示。 this.setLocationRelativeTo(null);
// 设置窗体关闭时退出程序。 this.setDefaultCloseOperation(3);
// 设置窗体可见 this.setVisible(true);
// 获取窗体画布对象 java.awt.Graphics g = this.getGraphics();
java.awt.event.MouseAdapter ml = new DrawListener(g);
2、鼠标对界面的控制:用匿名内部类实现动作监听器,并给每个按钮添加动作监听。
// 创建动作监听器的对象。 java.awt.event.ActionListener al = new java.awt.event.ActionListener()
//在匿名内部类中定义不同按钮的操作方法。
//在界面上对按钮添加动作监听.btnLine.addActionListener(al);
添加鼠标监听器通过对接口的实现,来定义不同按钮的操作方法。
3、画布上图形的重绘。
在鼠标监听器中创建一个队列对象,用来封装画布上的图形。然后在窗体上重写重绘的方法的方法,将队列中存储的图形取出,再重新画到画布上。
//创建一个队列对象,用来封装图形对象 public static ArrayList<Graph> list = new ArrayList<Graph>();
4、画图板的保存
再主类中分别定义保存和对取数据的方法,运用流的功能,实现数据在文件与内存中的互相转换。
在界面上再添加两个保存和打开的按钮,在匿名内部类中定义按钮的实现方法。
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
/**
* 定义DrawFrame类,继承JFrame类
*
* @author Wangshuo
*
*/
public class DrawFrame extends JFrame {
/*
* 主函数
*/
public static void main(String[] args) {
// 创建DrawFrame类对象
DrawFrame hb = new DrawFrame();
// 调用初始化界面的方法
hb.init();
}
/*
* 初始化画板界面
*/
public void init() {
// 设置窗体的标题
this.setTitle("画板");
// 设置窗体的大小
this.setSize(800, 650);
// 设置窗体的居中显示
this.setLocationRelativeTo(null);
// 设置窗体关闭时退出程序
this.setDefaultCloseOperation(3);
// 设置窗体可以最大化
this.setResizable(true);
// 创建流体布局对象
java.awt.FlowLayout f1 = new java.awt.FlowLayout();
// 设置流体布局
this.setLayout(f1);
// 创建颜色按钮
javax.swing.JButton btnColor = new javax.swing.JButton("颜色");
// 设置按钮的动作命令
btnColor.setActionCommand("Color");
// 将按钮添加到窗体上
this.add(btnColor);
// 创建直线按钮
javax.swing.JButton btnLine = new javax.swing.JButton("直线");
// 设置按钮的动作命令
btnLine.setActionCommand("Line");
// 将按钮添加到窗体上
this.add(btnLine);
// 创建矩形按钮
javax.swing.JButton btnRect = new javax.swing.JButton("矩形");
// 设置按钮动作监听命令
btnRect.setActionCommand("Rect");
// 将按钮添加到窗体上
this.add(btnRect);
// 创建椭圆按钮
javax.swing.JButton btnRval = new javax.swing.JButton("椭圆");
// 设置按钮动作监听命令
btnRval.setActionCommand("Rval");
// 将按钮添加到窗体上
this.add(btnRval);
// 创建曲线按钮
javax.swing.JButton btnBend = new javax.swing.JButton("曲线");
// 设置按钮动作监听命令
btnBend.setActionCommand("Bend");
// 将按钮添加到窗体上
this.add(btnBend);
// 创建保存按钮
javax.swing.JButton btnSave = new javax.swing.JButton("保存");
// 设置按钮动作监听命令
btnSave.setActionCommand("Save");
// 将按钮添加到窗体上
this.add(btnSave);
// 创建打开按钮
javax.swing.JButton btnOpen = new javax.swing.JButton("打开");
// 设置按钮动作监听命令
btnOpen.setActionCommand("Open");
// 将按钮添加到窗体上
this.add(btnOpen);
// 使用匿名内部类来实现动作监听器
// 创建动作监听器的对象
java.awt.event.ActionListener al = new java.awt.event.ActionListener() {
// 动作事件处理方法
public void actionPerformed(ActionEvent e) {
System.out.println(">>>>>" + e.getActionCommand());
// 判断点击的是哪一个按钮
if (e.getActionCommand().equals("Color")) {
color = javax.swing.JColorChooser.showDialog(null, "请选择颜色",
Color.BLACK);
} else if (e.getActionCommand().equals("Save")) {
DrawFrame df = new DrawFrame();
df.saveFile("D:\\aa.as", DrawListener.list);
} else if (e.getActionCommand().equals("Open")) {
DrawFrame df = new DrawFrame();
DrawListener.list = df.readFile("D:\\aa.as");
System.out.println(">>>>" + DrawListener.list.size());
repaint();
} else {
item = e.getActionCommand();
}
}
};
// 给按钮添加动作监听器方法
btnLine.addActionListener(al);
btnRect.addActionListener(al);
btnRval.addActionListener(al);
btnColor.addActionListener(al);
btnBend.addActionListener(al);
btnSave.addActionListener(al);
btnOpen.addActionListener(al);
// 设置窗体可见
this.setVisible(true);
// 获取窗体画布对象
java.awt.Graphics g = this.getGraphics();
java.awt.event.MouseAdapter ml = new DrawListener(g);
// 设置窗体的鼠标监听器方法,绑定到处理对象
this.addMouseListener(ml);
this.addMouseMotionListener(ml);
}
/**
* 重写窗体的重绘方法
*/
public void paint(Graphics g) {
// 调用父类的paint方法
super.paint(g);
// 调用队列
for (int i = 0; i < DrawListener.list.size(); i++) {
// 取出队列中的每一个元素,使用强制转型转换为Graph类型
Graph gra = DrawListener.list.get(i);
if (gra.getItem().equals("Rval")) {
g.setColor(gra.getColor());
g.fillOval(gra.getX1(), gra.getY1(), gra.getX2(), gra.getY2());
} else if (gra.getItem().equals("Rect")) {
g.setColor(gra.getColor());
g.drawRect(gra.getX1(), gra.getY1(), gra.getX2(), gra.getY2());
} else if (gra.getItem().equals("Bend")) {
// 开始画相应的图形
g.setColor(gra.getColor());
g.drawLine(gra.getX1(), gra.getY1(), gra.getX2(), gra.getY2());
} else if (gra.getItem().equals("Line")) {
g.setColor(gra.getColor());
g.drawLine(gra.getX1(), gra.getY1(), gra.getX2(), gra.getY2());
}
}
}
public void saveFile(String path, ArrayList<Graph> list) {
try {
// 创建文件输出流
java.io.OutputStream ops = new java.io.FileOutputStream(path);
// 将文件输出流包装成
java.io.DataOutputStream dos = new java.io.DataOutputStream(ops);
// 将队列写入图形个数
dos.writeInt(list.size());
// 读取队列
for (int i = 0; i < list.size(); i++) {
// 取出一种形状
Graph li = list.get(i);
String str = li.getItem();
byte by = 4;
if(str.equals("Line")){
by = 0;
}else if(str.equals("Rval")){
by = 1;
}else if(str.equals("Rect")){
by = 2;
}else if(str.equals("Bend")){
by = 3;
}
// 写形状的类型
dos.writeByte(by);
if (by == 0) {
// 如果类型为直线
// 写入直线数据
int x1 = li.getX1();
int y1 = li.getY1();
int x2 = li.getX2();
int y2 = li.getY2();
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (by == 1) {
// 如果类型为圆
// 写入圆数据
int x1 = li.getX1();
int y1 = li.getY1();
int x2 = li.getX2();
int y2 = li.getY2();
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (by == 2) {
// 如果类型为矩形
// 写入矩形数据
int x1 = li.getX1();
int y1 = li.getY1();
int x2 = li.getX2();
int y2 = li.getY2();
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
} else if (by == 3) {
// 如果类型为曲线
// 写入曲线数据
int x1 = li.getX1();
int y1 = li.getY1();
int x2 = li.getX2();
int y2 = li.getY2();
dos.writeInt(x1);
dos.writeInt(y1);
dos.writeInt(x2);
dos.writeInt(y2);
System.out.println("我画曲线了!");
}
//写入颜色 a:蓝色,b:绿色,c:红色
Color co = li.getColor();
int a = co.getBlue();
int b = co.getGreen();
int c = co.getRed();
dos.writeInt(a);
dos.writeInt(b);
dos.writeInt(c);
}
dos.flush();
ops.close();
} catch (Exception df) {
df.printStackTrace();
}
}
public java.util.ArrayList<Graph> readFile(String path) {
// 创建一个队列用来保存从文件中读取到的数据
java.util.ArrayList<Graph> shape = new java.util.ArrayList<Graph>();
try {
// 创建文件对象输入流
java.io.FileInputStream fis = new java.io.FileInputStream(path);
// 将文件输入流包装成可读基本类型流
java.io.DataInputStream dis = new java.io.DataInputStream(fis);
// 读取长度,即总形状个数
int len = dis.readInt();
for (int i = 0; i < len; i++) {
byte type = dis.readByte();
if (type == 0) {
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
int a = dis.readInt();
int b = dis.readInt();
int c = dis.readInt();
Color color = new java.awt.Color(a,b,c);
item = "Line";
Graph li = new Graph(color, item, x1, y1, x2, y2);
shape.add(li);
} else if (type == 1) {
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
int a = dis.readInt();
int b = dis.readInt();
int c = dis.readInt();
Color color = new java.awt.Color(a,b,c);
item = "Rval";
Graph li = new Graph(color, item, x1, y1, x2, y2);
shape.add(li);
System.out.println("我要保存圆了");
} else if (type == 2) {
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
int a = dis.readInt();
int b = dis.readInt();
int c = dis.readInt();
Color color = new java.awt.Color(a,b,c);
item = "Rect";
Graph li = new Graph(color, item, x1, y1, x2, y2);
shape.add(li);
System.out.println("我要保存矩形了");
} else if (type == 3) {
int x1 = dis.readInt();
int y1 = dis.readInt();
int x2 = dis.readInt();
int y2 = dis.readInt();
int a = dis.readInt();
int b = dis.readInt();
int c = dis.readInt();
Color color = new java.awt.Color(a,b,c);
item = "Bend";
Graph li = new Graph(color, item, x1, y1, x2, y2);
shape.add(li);
System.out.println("我要保存曲线了");
}
}
} catch (Exception ef) {
ef.printStackTrace();
}
System.out.println("读取到的现状个数:" + shape.size());
return shape;
}
// 定义一个静态的公有颜色的属性
public static java.awt.Color color = java.awt.Color.BLACK;
// 定义一个静态的公有的图形的属性
public static String item ;
}
import java.awt.event.MouseEvent;
import java.util.ArrayList;
/**
* 画图形的监听类
*
* @author Administrator
*
*/
public class DrawListener extends java.awt.event.MouseAdapter{
// 定义四个保存坐标值的变量
private int x1, x2, y1, y2;
// 定义一个画图形的画布类对象
private java.awt.Graphics g;
// 定义一个统计点击次数的计数器
@SuppressWarnings("unused")
private int count = 0;
//创建一个队列对象,用来封装图形对象
public static ArrayList<Graph> list = new ArrayList<Graph>();
// 定义一个带参数的构造函数,带的参数是画布对象
public DrawListener(java.awt.Graphics g) {
this.g = g;
}
public void mousePressed(MouseEvent e) {
// 如果计数器为零
//if(count ==0){
x1 = e.getX();
y1 = e.getY();
//if(!DrawFrame.item.equals("Bend"))
// 让计数器加1
// count ++;
//}else{
// 如果计数器为1
}
public void mouseReleased(MouseEvent e) {
// 获取鼠标在窗体上单击时的坐标
x2 = e.getX();
y2 = e.getY();
// 让计数器减1
// count--;
// 判断所击的按钮命令
if (DrawFrame.item.equals("Line")) {
// 开始画相应的图形
g.setColor(DrawFrame.color);
g.drawLine(x1, y1, x2, y2);
//创建对象,将对象封装到队列中
Graph gra = new Graph(DrawFrame.color,DrawFrame.item,x1,y1,x2,y2);
list.add(gra);
} else if (DrawFrame.item.equals("Rval")) {
g.setColor(DrawFrame.color);
// g.drawOval(x1,y1,x2,y2);
g.fillOval(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));
//创建对象,将对象封装到队列中
Graph gra = new Graph(DrawFrame.color,DrawFrame.item,x1,y1,Math.abs(x2 - x1),Math.abs(y2 - y1));
list.add(gra);
} else if (DrawFrame.item.equals("Rect")) {
g.setColor(DrawFrame.color);
g.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));
//创建对象,将对象封装到队列中
Graph gra = new Graph(DrawFrame.color,DrawFrame.item,x1,y1,Math.abs(x2 - x1), Math.abs(y2 - y1));
list.add(gra);
}
}
public void mouseDragged(MouseEvent e){
if (DrawFrame.item.equals("Bend")) {
// 获取鼠标在窗体上单击时的坐标
x2 = e.getX();
y2 = e.getY();
// 开始画相应的图形
g.setColor(DrawFrame.color);
g.drawLine(x1, y1, x2, y2);
//创建对象,将对象封装到队列中
Graph gra = new Graph(DrawFrame.color,DrawFrame.item,x1,y1,x2,y2);
list.add(gra);
//交换坐标值
x1 = x2;
y1 = y2;
}
}
}