前言 前面自制了画图工具,可以在java制作的画图界面上进行画图编辑,但是问题是,当我们点击画图工具的缩小放大栏时,我们画的图形会被擦除,这涉及到一个java内部自带paint类的功用,我们所要做的,就是保存我们画的图形,这样当画图界面还原的时候,能够重现我们原本所画的图形。
这里定义的 shape类是为了创建一个对象,从而保存我们的图形,比如,我们画了一条直线,那么我们需要保存两个点,这样,当我们重新画的时候,就有了依据。
// An highlighted block
package cz0822;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
/*
这里新建立一个SHape类,用于保存各个图形的点,IFS对象(分形),画笔颜色等。
*/
public class Shape {
private JFrame jj;
private int x1,x2,y2,y1;//图像点坐标,如果是直线,那就是起止两个坐标,如果是矩形,就是对角线的两个点
private String name;//画什么样的图形
private int [] array1;//多边形点坐标
private int []array2;
private int []array3;
private int [] array4;
private IFS II;//分性对象
private int end;
private Color color;//图形颜色
public Shape(int x1,int y1,int x2,int y2,String name,int []array1,int []array2,int[]array3,int[]array4,int f,IFS II,Color color) {
this.x1=x1;
this.x2=x2;
this.y1=y1;
this.y2=y2;
this.name=name;
this.array1=array1;
this.array2=array2;
this.array3=array3;
this.array4=array4;
this.end=f;
this.II=II;
this.color=color;
}
/*
这部分实现复现功能,传递的参数有两个,画笔对象和JFrame对象
*/
public void reshape(Graphics G,JFrame JF) {
jj=JF;
G.setColor(color);
switch(name) {
case"直线":
G.drawLine(x1, y1, x2, y2);
break;
case"矩形":
G.drawRect(Math.min(x1, x2),Math.min(y2,y1) ,Math.abs(x2-x1),Math.abs(y2-y1));
break;
case"多边形":
G.drawLine(x1, y1, x2, y2);
break;
case"分形":
II.set(G);
break;
case"铅笔":
Graphics2D g = (Graphics2D) G;
g.setStroke(new BasicStroke(2));// 设置线条的粗细
G.drawLine(x1, y1, x2, y2);
break;
case"刷子":
Graphics2D gg = (Graphics2D) G;
gg.setStroke(new BasicStroke(10));// 设置线条的粗细
G.drawLine(x1, y1, x2, y2);
break;
case"橡皮":
Color color = jj.getContentPane().getBackground();
Graphics2D gd = (Graphics2D) G;
gd.setColor(new Color(238, 238, 238));// 设置颜色为窗体颜色
gd.setStroke(new BasicStroke(50));
gd.drawLine(x1, y1, x2, y2);// 画曲线
break;
}
}
}
这里定义的 shape类是为了创建一个对象,从而保存我们的图形,比如,我们画了一条直线,那么我们需要保存两个点,这样,当我们重新画的时候,就有了依据。
private shape[]newshape;
''''
public void setarray(shape[] a) {
newshape = a;
}
/*
我们在mouse类中新设置了一个私有对象,这个对象属于Shape型,
这里在监听器类中设置一个setarray方法,将a数组的地址赋给newshape,这样, 数组在java中引用数据类型,int是基本数据类型,我们的数组对象shapearray相当于一个指针,把这个对象传递mouse类中,这个时候mouse类跟paint类中操作的同一个对象,所以当mouse类往数组存数据,paint类就能直接拿出来用.
*/
/*接下来的这一部分就是这个shape数组的具体应用,画直线的时候,把四个坐标参数放入shape类中,这样shape数组中就成功保存了一个新对象*/
if ("直线".equals(name)) {
// 画图形
gr.drawLine(x1, y1, x2, y2);
IFS II=new IFS();
shape s = new shape(x1, y1, x2, y2, name, array1, array2, array3, array4, index1,II,color);
newshape[index++] = s;
}
/*画矩形的时候,把四个参数作为参数传递给shape类,这样,又成功保存了一个对象
*/
if ("矩形".equals(name)) {
// 矩形
gr.drawRect(Math.min(x1, x2), Math.min(y2, y1), Math.abs(x2 - x1), Math.abs(y2 - y1));
IFS II=new IFS();
shape s = new shape(x1, y1, x2, y2, name, array1, array2, array3, array4, index1,II,color);
newshape[index++] = s;
}
前面说过,定义了一个shape类,保存了复现对象,那么paint实现的功能就是调用这个shape类。
// An highlighted block
package cz0822;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
/*
注意看这里,定义的Paint类继承了JFrame窗体对象呢,这是为什么呢?
因为实现复现,需要用到paint函数,而paint函数是JFrame类中特有的,那么我们这里相当于重写JFrame中的paint函数,这里和接口的概念十分相近
*/
public class Paint extends JFrame{
public static void main(String[] args) {
Paint f = new Paint();
f.initUI();
}
Shape []shapearray=new Shape[10000];
public void initUI() {
// 窗体对象
//thisrame this = new thisrame("画图");
// 像素 > 分辨率
this.setSize(800, 700);
// 设置居中显示
this.setLocationRelativeTo(null);
// 设置退出进程
this.setDefaultCloseOperation(3);
//流式布局管理器
FlowLayout flow = new FlowLayout();
this.setLayout(flow);
Mouse mouse = new Mouse();
JMenuBar menubar = new JMenuBar();// 菜单条 容器
JMenu menu = new JMenu("File"); // 菜单
menu.setMnemonic(KeyEvent.VK_F);
JMenu menu1 = new JMenu("RunAs"); // 菜单
JMenuItem menuItem = new JMenuItem("run"); // 菜单项 -- 动作监听器监听
JMenuItem menuItem1 = new JMenuItem("JavaAPP");
menu.add(menu1);
menu1.add(menuItem1);
menubar.add(menu);
menu.add(menuItem);
this.setJMenuBar(menubar);
menuItem.addActionListener(mouse);
menuItem1.addActionListener(mouse);
String []ju= {"直线","矩形","多边形","分形","人物","铅笔","刷子","橡皮"};
for(int i=0;i<ju.length;i++) {
JButton JB=new JButton(ju[i]);
this.add(JB);//先把这个按钮放在窗体中
JB.addActionListener(mouse);//然后给这个按钮加上监听器
}
Color [] color= {Color.red,Color.white,Color.GREEN,Color.blue,Color.GRAY};
for(int i=0;i<color.length;i++) {
JButton CC=new JButton();
CC.setBackground(color[i]);//给按钮设置颜色
CC.setPreferredSize(new Dimension(20,20));//给按钮设置大小
this.add(CC);//把按钮放入窗体中
CC.addActionListener(mouse);//给按钮加上监听器
}
this.setVisible(true);
//画笔:图形画在那个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象,一定要在窗体显示可见之后
Graphics G=this.getGraphics();//定义画笔,这个画笔G是在窗体上画的,所以要设置在this这窗体上
this.addMouseListener(mouse);
this.addMouseMotionListener(mouse);
mouse.setGr(G,this);
mouse.setshape(shapearray);
//这里将shape数组传给mouse类中,数组在java中引用数据类型,int是基本 数据类型,我们的数组对象shapearray相当于一个指针,把这个对象传递mouse类中,这个时候mouse类跟paint类中操作的同一个对象,所以当mouse类往数组存数据,paint类就能直接拿出来用
}
/*
JFrame中有一个函数paint,我们需要调用这个函数来实现复现功能,
这里可以认为是一种公式,我们需要实现复现功能时,可以使用这个模板
public void paint(Graphics G) {
super.paint(G);
。。。。
}
*/
public void paint(Graphics G) {
super.paint(G);
for(int i=0;i<shapearray.length;i++) {
Shape s=shapearray[i];
if(s!=null) {
s.reshape(G,this);
}
}
}
}