在之前所制造的画板窗体中实现了画出各种图形,但可以发现当我们缩放窗体时此时并未保留我们所画出的图形。应为窗体实现了改变大小是重新渲染绘制的方法,但我们所绘制的图形,并非是窗体的一部分,因此我们要实现窗体刷新时将保存的图形再绘制一遍。此时就需要重写窗体中重新绘制的方法。
继承
如何重写方法就需要我们了解继承。
1.类与类之间的关系,子类可以继承父类的方法
如学生类中存在工科学生与文科理科学生,那么工科理科文科学生都可以称作学生类的子类。
语法:public class 类名 extends 父类名{}
1.1:一个类只能有一个直系父类,但父系类也算做父类
1.2:一个类可以实现(implements)多个接口,接口与接口之间也可继承
方法重写:
格式:方法结构必须与父类一致,方法体可以修改。
子类重写父类的方法,可以基于父类的方法进行扩展 升级 重构具体化。
与同类中多个方法名的方法值的是方法的重载(参数不一样)
子类以及子类对象会先调用重写后的方法。
练习:
之前创造窗体是我们是直接导包后创建窗体对象。那么我们重写方法就需继承窗体
public class DrawUI extends JFrame {}
同样设置好窗体的属性:窗体名,尺寸,关闭方式,布局。我们可以直接使用JFrame中的方法。
public void shouUI(){
//画板设置
setTitle("画板");
setSize(900,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
FlowLayout fl = new FlowLayout();
setLayout(fl);
接着设置所需要的按钮,在之前的创建中,我们一个个的按钮来是实现,这次过多按钮时可以通过创建一个字符串数组来存储按钮的名字,以及Color数组来储存我们所需要的颜色。接着通过循环来创建按钮,同时将按钮添加到窗体中,并且添加按钮监听:
String[] jbs = {"直线","矩形","实心矩形","圆","实心圆","三角形","等腰三角形","多边形","撤回","清空","橡皮擦","立方体"};
Color[] btnColors = {Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,Color.GRAY,Color.GREEN,Color.LIGHT_GRAY,Color.MAGENTA,
Color.PINK,Color.ORANGE,Color.RED,Color.WHITE,Color.YELLOW
};
ActionMouse am = new ActionMouse();
for (int i = 0; i < jbs.length; i++) {
JButton jbn = new JButton(jbs[i]);
add(jbn);
jbn.addActionListener(am);
}
for (int i = 0; i < btnColors.length; i++) {
JButton jbn1 = new JButton();
jbn1.setBackground(btnColors[i]);
jbn1.setPreferredSize(new Dimension(50,20));
add(jbn1);
jbn1.addActionListener(am);
}
设置可见后,同时添加鼠标监听以及将我们的画笔传入实现鼠标与按钮监听类中。
setVisible(true);
addMouseListener(am);//添加鼠标监管
am.g = getGraphics();//将画笔传过去
}
接着创建一个一个类实现我们上面鼠标与按钮监听:
public class ActionMouse implements MouseListener, ActionListener {}
在这个类中需要定义我们前面所传过来的画笔以及需要使用的坐标,颜色。
Graphics g;
String type = "直线";
int x1,y1,x2,y2,x3,y3,x4,y4,x5,y5;
Color color = Color.BLACK;
在实现画出直线,圆等需要两个坐标可以绘制出来的图形,可以将其创建在一个类TwoPoint中,创建对象调用其中的方法创建出。同时在实现监听的类中创建出TwoPoint类型的数组用来存储每次画出的图形,以便实现重绘。
package lcr0402;
import java.awt.*;
public class TwoPoint {
int x1,y1,x2,y2;
String type;
Color color;
public TwoPoint(int x1, int y1, int x2, int y2, String type, Color color){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.type = type;
this.color = color;
}
public TwoPoint(){//默认构造
}
public void twoPaint(Graphics g){
if(type.equals("直线")){
g.setColor(color);
g.drawLine(x1,y1,x2,y2);
} else if (type.equals("矩形")) {
g.setColor(color);
g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
} else if (type.equals("实心矩形")) {
g.setColor(color);
g.fillRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
} else if (type.equals("圆")) {
g.setColor(color);
g.drawOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
} else if (type.equals("实心圆")) {
g.setColor(color);
g.fillOval(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));
}
}
}
Graphics g;
String type = "直线";
int x1,y1,x2,y2,x3,y3,x4,y4,x5,y5;
Color color = Color.BLACK;
TwoPoint[] shapeArray = new TwoPoint[100];
int subscript1 = 0;
@Override
public void mousePressed(MouseEvent e) {
x1 = e.getX();
y1 = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
if(subscript1 >100){
shapeArray = copeOf(shapeArray);
}
x2 = e.getX();
y2 = e.getY();
//存储图形的扩容
//
if(type.equals("直线")||type.equals("矩形")||type.equals("实心矩形")||type.equals("圆")||type.equals("实心圆")) {
TwoPoint tp = new TwoPoint(x1,y1,x2,y2,type,color);
tp.twoPaint(g);
shapeArray[subscript1] = tp;
subscript1++;
}
}
在画三角形及其多边形时如果我们选用调用画多边形的方法,g.drawPolygon();传入里面的参数会发现无法实现重绘。以为传过去的数组实际传过去的是地址当我们二次绘画需要将前面的数据初始化,也无法像画直线存入创建的数组中。因此我们依旧采用画直线的方式来实现。同时从第二次点击开始,每次点击都需存入绘制直线的坐标:
@Override
public void mouseClicked(MouseEvent e) {
if(type.equals("三角形")){
if(count ==0){
x3 = e.getX();
y3 = e.getY();
count++;
} else if (count == 1) {
x4 = e.getX();
y4 = e.getY();
Polygon pl = new Polygon(x3, y3, x4, y4, color);
pl.drawPolygon(g);
simpleArray[subscript3] = pl;
subscript3++;
count++;
} else if (count ==2) {
x5 = e.getX();
y5 = e.getY();
Polygon pl = new Polygon(x5, y5, x4, y4, color);
Polygon pl1 = new Polygon(x5, y5, x3, y3, color);
pl.drawPolygon(g);
pl1.drawPolygon(g);
simpleArray[subscript3] = pl;
subscript3++;
simpleArray[subscript3] = pl1;
subscript3++;
count = 0;
}
} else if (type.equals("多边形")) {
if (count == 0) {
x3 = e.getX();
y3 = e.getY();
count++;
} else if (count == 1) {
x4 = e.getX();
y4 = e.getY();
Polygon pl = new Polygon(x3, y3, x4, y4, color);
pl.drawPolygon(g);//调用方法
thereArray[subscript2] = pl;
subscript2++;
count++;
} else if (count == 2) {
x5 = e.getX();
y5 = e.getY();
if(Math.sqrt(Math.pow(x5-x3,2)+Math.pow(y5-y3,2)) < 100){
Polygon pl = new Polygon(x5, y5, x3, y3, color);
Polygon pl1 = new Polygon(x5, y5, x4, y4, color);
pl.drawPolygon(g);
pl1.drawPolygon(g);
thereArray[subscript2] = pl;
subscript2++;
thereArray[subscript2] = pl1;
subscript2++;
count =0;
} else {
Polygon pl = new Polygon(x5, y5, x4, y4, color);
pl.drawPolygon(g);
thereArray[subscript2] = pl;
subscript2++;
x4 = x5;
y4 = y5;
count = 2;
}
}
}
}
package lcr0402;
import java.awt.*;
public class Polygon {
int x1,y1,x2,y2;
Color color = Color.BLACK;
public Polygon(int x1, int y1, int x2, int y2, Color color){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.color = color;
}
public void drawPolygon(Graphics g){
g.setColor(color);
g.drawLine(x1,y1,x2,y2);
System.out.println("绘制");
}
}
接着我们实现拉动窗体后的重绘
在窗体界面中重写paint()方法:
@Override
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < am.subscript1; i++) {
TwoPoint tp = am.shapeArray[i];//类似赋值
tp.twoPaint(g);
}
for (int i = 0; i < am.subscript2; i++) {
Polygon tp3 = am.thereArray[i];
tp3.drawPolygon(g);
}
for (int i = 0; i < am.subscript3; i++) {
Polygon tp2 = am.simpleArray[i];
tp2.drawPolygon(g);
}
}
super.paint(g);调用父类的重绘方法,同时在下面实现新的重绘,将我们所存储的数组通过循环一个个重新绘制。便可实现重绘。