【练习】面向对象系列(004)——在自定义窗口中画矩形、直线、椭圆
作业:在自定义窗口中添加:矩形、直线、椭圆三个按钮,点击矩形按钮画矩形并计算矩形面积及周长、点击直线按钮则画直线并计算直线长度、点击椭圆按钮画椭圆并计算椭圆面积和周长。
package cn.libill.test;
import cn.libill.ui.MyFrame;
/**
* 测试类
* @author libill
*
*/
public class MyFrameTest {
public static void main(String[] args) {
new MyFrame().setVisible(true);
}
}
自定义窗口大小,样式,布局等,并添加按钮,为按钮添加监听器,重写paint方法
package cn.libill.ui;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import cn.libill.util.MyUtil;
import cn.liblill.shape.Line;
import cn.liblill.shape.Oval;
import cn.liblill.shape.Rectangle;
import cn.liblill.shape.Shape;
/**
* 自定义窗口
* @author libill
*
*/
@SuppressWarnings("serial")
public class MyFrame extends JFrame {
private JButton lineButton;
private JButton recButton;
private JButton ovalButton;
private Shape shape = null;
private class ButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Line")) {
shape = new Line();
} else if (command.equals("Oval")) {
shape = new Oval();
} else {
shape = new Rectangle();
}
//设置图形的起点和终点(随机)
shape.setX1(MyUtil.random(10, 980));
shape.setY1(MyUtil.random(100, 580));
shape.setX2(MyUtil.random(10, 980));
shape.setY2(MyUtil.random(100, 580));
shape.setColor(MyUtil.createRandomColor());
repaint();
}
}
public MyFrame() {
this.setTitle("围棋"); //设置窗口标题
this.setSize(1000, 600); //设置窗口大小
this.setResizable(false); //不可调整窗口大小
this.setDefaultCloseOperation(EXIT_ON_CLOSE); //关闭窗口时退出程序(后台)
this.setLocationRelativeTo(null); //窗口居中
lineButton = new JButton("Line"); //添加按钮
recButton = new JButton("Rectangle");
ovalButton = new JButton("Oval");
ActionListener handler = new ButtonHandler();
//添加监听器
lineButton.addActionListener(handler);
recButton.addActionListener(handler);
ovalButton.addActionListener(handler);
this.setLayout(new FlowLayout()); //流氏布局管理器,从左到右依次摆放
this.add(lineButton);
this.add(recButton);
this.add(ovalButton);
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (shape != null) {
shape.draw(g);
if (shape instanceof Line) {
g.drawString("线条长度 = " + ((Line) shape).lineLength(), 40, 55);
} else if (shape instanceof Oval) {
g.drawString("椭圆面积 = " + ((Oval) shape).area(), 40, 50);
g.drawString("椭圆周长 = " + ((Oval) shape).perimeter(), 40, 64);
} else {
g.drawString("矩形面积 = " + ((Rectangle) shape).area(), 40, 50);
g.drawString("矩形周长 = " + ((Rectangle) shape).perimeter(), 40, 64);
}
}
}
}
图形抽象类,其子类必须实现draw( )方法
package cn.liblill.shape;
import java.awt.Color;
import java.awt.Graphics;
/**
* 图形抽象类
* @author libill
*
*/
public abstract class Shape {
protected int x1; //起点横坐标
protected int y1; //起点纵坐标
protected int x2; //终点横坐标
protected int y2; //终点纵坐标
protected Color color; //画笔颜色
/**
* 绘画(抽象方法留给子类实现)
* @param g 画笔
*/
public abstract void draw(Graphics g);
/**
* 起点横坐标访问器
* @return 起点横坐标
*/
public int getX1() {
return x1;
}
/**
* 起点横坐标修改器
* @param x1 起点横坐标
*/
public void setX1(int x1) {
this.x1 = x1;
}
/**
* 起点纵坐标访问器
* @return 起点纵坐标
*/
public int getY1() {
return y1;
}
/**
* 起点纵坐标修改器
* @param y1 起点纵坐标
*/
public void setY1(int y1) {
this.y1 = y1;
}
/**
* 终点横坐标访问器
* @return 终点横坐标
*/
public int getX2() {
return x2;
}
/**
* 终点横坐标修改器
* @param x2 终点横坐标
*/
public void setX2(int x2) {
this.x2 = x2;
}
/**
* 终点纵坐标访问器
* @return 终点纵坐标
*/
public int getY2() {
return y2;
}
/**
* 终点纵坐标修改器
* @param y2 终点纵坐标
*/
public void setY2(int y2) {
this.y2 = y2;
}
/**
* 画笔颜色修改器
* @param color 画笔颜色
*/
public void setColor(Color color) {
this.color = color;
}
}
package cn.liblill.shape;
import java.awt.Graphics;
/**
* 矩形类,继承父类Shape
* @author libill
*
*/
public class Rectangle extends Shape {
@Override
public void draw(Graphics g) {
int startX = x1 < x2 ? x1 : x2;
int startY = y1 < y2 ? y1 : y2;
int endX = x1 > x2 ? x1 : x2;
int endY = y1 > y2 ? y1 : y2;
int width = Math.abs(endX - startX);
int height = Math.abs(endY - startY);
g.setColor(color);
g.drawRect(startX, startY, width, height);
}
/**
* 计算矩形面积
* @return 矩形面积
*/
public double area() {
return Math.abs(x2 - x1) * Math.abs(y2 - y1);
}
/**
* 计算矩形周长
* @return 矩形周长
*/
public double perimeter() {
return (Math.abs(x2 - x1) + Math.abs(y2 - y1)) * 2;
}
}
package cn.liblill.shape;
import java.awt.Graphics;
/**
* 椭圆类,继承父类Shape
* @author libill
*
*/
public class Oval extends Shape {
@Override
public void draw(Graphics g) {
int startX = x1 < x2 ? x1 : x2;
int startY = y1 < y2 ? y1 : y2;
int endX = x1 > x2 ? x1 : x2;
int endY = y1 > y2 ? y1 : y2;
int width = Math.abs(endX - startX);
int height = Math.abs(endY - startY);
g.setColor(color);
g.drawOval(startX, startY, width, height);
}
/**
* 计算椭圆面积
* @return 椭圆面积
*/
public double area() {
return Math.PI * Math.abs(x2 - x1) * Math.abs(y2 - y1) / 4;
}
/**
* 计算椭圆周长
* @return 椭圆周长
*/
public double perimeter() {
int width = Math.abs(x2 - x1);
int height = Math.abs(y2 - y1);
double a = width > height ? width / 2 : height / 2; //a为长半轴
double b = width < height ? width / 2 : height / 2; //b为短半轴
return 2 * Math.PI * b + 4 * (a - b);
}
}
package cn.liblill.shape;
import java.awt.Graphics;
/**
* 直线类,继承父类Shape
* @author libill
*
*/
public class Line extends Shape {
@Override
public void draw(Graphics g) {
g.setColor(color);
g.drawLine(x1, y1, x2, y2);
}
/**
* 计算线条长度
* @return 线条长度
*/
public double lineLength() {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
}
package cn.libill.util;
import java.awt.Color;
/**
* 自定义工具类
* @author libill
*
*/
public final class MyUtil { //加final表明该类不能被继承,没有任何子类(断子绝孙类)
/**
* 将构构器私有,不能在外部创建MyUtil类,要访问该类中的方法,只能用(MyUtil.)来调用
*/
private MyUtil() {
}
/**
* 产生指定范围的随机数
* @param min 最小值 (闭区间)
* @param max 最大值 (闭区间)
* @return 指定范围的随机数
*/
public static int random(int min, int max) {
return (int) (Math.random() * (max - min + 1) + min);
}
/**
* 生成随机颜色
* @return Color对象
*/
public static Color createRandomColor() {
int r = random(0, 255);
int g = random(0, 255);
int b = random(0, 255);
return new Color(r, g, b);
}
}