【练习】面向对象系列(005)——在自定义窗口中画矩形、直线、椭圆、涂鸦
要求:创建一个图形窗口添加四个按钮,每个按钮对应画一种图形, 并为其添加一个用户登录界面,只有在正确登录的时候才能进入画图软件画图
package cn.libill.test;
import cn.libill.ui.LoginFrame;
/**
* 测试类
* @author libill
*
*/
public class MyFrameTest {
public static void main(String[] args) {
//new MyFrame().setVisible(true);
new LoginFrame().setVisible(true);
}
}
package cn.libill.ui;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
/**
* 登录界面
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class LoginFrame extends JDialog {
private JLabel uidLabel, pwdLabel;
private JTextField uidField;
private JPasswordField pwdField;
private JButton loginButton, cancelButton;
private List<User> userList = new ArrayList<User>();
public LoginFrame() {
this.setTitle("用户登录");
this.setSize(300, 180);
this.setResizable(false);
this.setLocationRelativeTo(null);
// this.setDefaultCloseOperation(EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
userList.add(new User("admin", "123456"));
userList.add(new User("libill", "654321"));
userList.add(new User("jack", "111111"));
uidLabel = new JLabel("用户名: ");
pwdLabel = new JLabel("密码: ");
uidField = new JTextField();
pwdField = new JPasswordField();
loginButton = new JButton("登录");
cancelButton = new JButton("取消");
this.setLayout(null);
uidLabel.setBounds(40, 20, 50, 30);
pwdLabel.setBounds(40, 60, 50, 30);
uidField.setBounds(100, 25, 150, 20);
pwdField.setBounds(100, 65, 150, 20);
loginButton.setBounds(80, 100, 60, 30);
cancelButton.setBounds(160, 100, 60, 30);
this.add(uidLabel);
this.add(pwdLabel);
this.add(uidField);
this.add(pwdField);
this.add(loginButton);
this.add(cancelButton);
/**
* 添加登录按钮的监听器
*/
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (loginConfirm(userList)) {
new MyFrame(LoginFrame.this).setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "用户名或密码错误!", "错误", 0);
}
}
});
/**
* 点击取消按钮时退出后台
*/
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
/**
* 关闭窗口时退出后台
*/
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
/**
* 验证用户
* @param userList 用户列表
* @return true表示登录成功,否则false
*/
public boolean loginConfirm(List<User> userList) {
String username = uidField.getText().trim();
String password = new String(pwdField.getPassword());
for (int i = 0; i < userList.size(); ++i) {
if (userList.get(i).getUsername().equals(username)
&& userList.get(i).getPassword().equals(password)) {
return true;
}
}
return false;
}
}
package cn.libill.ui;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
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.Scrawl;
import cn.liblill.shape.Shape;
/**
* 自定义窗口
*
* @author libill
*
*/
@SuppressWarnings("serial")
public class MyFrame extends JFrame {
private JButton lineButton;
private JButton recButton;
private JButton ovalButton;
private JButton scrawlButton;
private Shape shape = null;
private List<Shape> shapeList = new ArrayList<Shape>();
private String type = "Line";
private boolean isMouseLeftButton; // 鼠标左键是否按下
private boolean isScrawlMode;
private BufferedImage bufferI = new BufferedImage(1000, 600, BufferedImage.TYPE_INT_RGB); //双缓冲,闪屏问题
private LoginFrame loginFrame;
/**
*
* @author Administrator
*
*/
private class ButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
type = e.getActionCommand();
}
}
public MyFrame(LoginFrame g) {
loginFrame = g;
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");
scrawlButton = new JButton("Scrawl");
this.setLayout(new FlowLayout()); // 流氏布局管理器,从左到右依次摆放
this.add(lineButton);
this.add(recButton);
this.add(ovalButton);
this.add(scrawlButton);
ButtonHandler handler = new ButtonHandler();
lineButton.addActionListener(handler);
recButton.addActionListener(handler);
ovalButton.addActionListener(handler);
scrawlButton.addActionListener(handler);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
loginFrame.setVisible(true);
}
});
this.addMouseListener(new MouseAdapter() {
/**
* 鼠标按下
*/
@Override
public void mousePressed(MouseEvent e) {
isMouseLeftButton = e.getButton() == MouseEvent.BUTTON1; // 鼠标左键按下
if (isMouseLeftButton) {
if (type.equals("Line")) {
shape = new Line();
} else if (type.equals("Oval")) {
shape = new Oval();
} else if (type.equals("Rectangle")) {
shape = new Rectangle();
} else {
isScrawlMode = true;
}
if (shape != null) {
int x;
int y;
x = e.getX();
y = e.getY();
shape.setX1(x);
shape.setY1(y);
shape.setX2(x);
shape.setY2(y);
shape.setColor(MyUtil.createRandomColor());
}
}
}
/**
* 鼠标释放
*/
@Override
public void mouseReleased(MouseEvent e) {
if (isMouseLeftButton && shape != null) {
shapeList.add(shape);
shape = null;
}
}
});
this.addMouseMotionListener(new MouseAdapter() {
/**
* 鼠标
*/
@Override
public void mouseDragged(MouseEvent e) {
// 只有在鼠标左键按下才画图
int x = e.getX();
int y = e.getY();
if (shape != null && isMouseLeftButton) {
shape.setX2(e.getX());
shape.setY2(e.getY());
} else if (isScrawlMode) {
Shape temp = new Scrawl(x, y);
temp.setColor(MyUtil.createRandomColor());
shapeList.add(temp);
}
repaint();
}
});
}
@Override
public void paint(Graphics g) {
Graphics g3 = bufferI.getGraphics();
super.paint(g3);
for (Shape temp : shapeList) {
temp.draw(g3);
}
if (shape != null) {
shape.draw(g3);
}
g.drawImage(bufferI, 0, 0, null);
}
}
package cn.libill.ui;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
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;
/**
* 直线类
* @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.liblill.shape;
import java.awt.Graphics;
/**
* 椭圆类
* @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;
/**
* 矩形类
* @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;
/**
* 涂鸦类(画小圆圈方式实现)
* @author Administrator
*
*/
public class Scrawl extends Shape {
private int width = 8;
private int height = 8;
private int x, y;
@Override
public void draw(Graphics g) {
g.setColor(color);
g.fillRect(x, y, width, height);
}
public Scrawl(int x, int y) {
this.x = x;
this.y = y;
}
}
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);
}
}
运行结果如下:
1 用户登录界面
2 画图界面