交互式画板 v2.0
用java实现一个简单的可交互式画图板
在v1.0的基础上,添加了更多的图形绘制功能,并优化了代码结构。
各个类的功能介绍
DrawPadv2
类:窗口的基础设置与可视化,并且添加鼠标监听器和动作监听器DrawListener
类:实现MouseListener
和ActionListener
接口,用于处理鼠标事件和按钮点击事件
具体操作
- 设置好窗体的基础属性
// 创建一个DrawListener对象
DrawListener dl = new DrawListener();
// 显示UI界面
public void showUI() {
// 创建一个JFrame对象
JFrame jf = new JFrame();
// 设置窗口标题
jf.setTitle("画板v2.0");
// 设置窗口大小
jf.setSize(850, 600);
// 设置窗口居中显示
jf.setLocationRelativeTo(null);
// 设置窗口关闭时的操作
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口布局为流式布局FlowLayout
jf.setLayout(new FlowLayout());
通过上述代码,我们创建了一个标题为 “画板 v2.0” 的窗口,设置其大小为 850x600 像素,并使其居中显示。同时,配置关闭窗口时终止程序运行,并采用流式布局(FlowLayout)管理组件排列。
2. 添加按钮和颜色按钮,并设置监听器
// 定义按钮类型
String [] btnType = {"直线", "圆形", "矩形", "实心圆形", "实心矩形", "等腰三角形",
"实心等腰三角形", "橡皮擦"};
// 循环创建按钮并添加到窗口中
for(int i = 0 ; i < btnType.length ; i++) {
JButton btn = new JButton(btnType[i]);
jf.add(btn);
// 为按钮添加监听器
btn.addActionListener(dl);
}
// 定义颜色按钮的颜色
Color[] btnColors = {Color.BLACK, Color.RED, Color.GREEN,
Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGENTA,
Color.GRAY, Color.LIGHT_GRAY, Color.DARK_GRAY,
Color.PINK, Color.ORANGE, Color.WHITE};
// 循环创建颜色按钮并添加到窗口中
for(int i = 0 ; i < btnColors.length ; i++) {
JButton btn = new JButton();
// 设置按钮的命令为ColorBtn
btn.setActionCommand("ColorBtn");
// 设置按钮的背景颜色
btn.setBackground(btnColors[i]);
jf.add(btn);
// 为按钮添加监听器
btn.addActionListener(dl);
}
// 设置窗口可见
jf.setVisible(true);
// 为窗口添加鼠标监听器
jf.addMouseListener(dl);
通过循环创建两类按钮:一类用于选择绘制图形的类型,另一类用于切换画笔颜色。每个按钮均绑定了统一的事件监听器dl(DrawListener对象),实现交互逻辑的集中处理
3. 在DrawListener
类中补全监听器中的方法,并创建一个Graphics对象
public class MouseListener implements java.awt.event.MouseListener {
// 声明Graphics对象
Graphics g;
public void actionPerformed(ActionEvent e) {
System.out.println("点击按钮");
}
public void mouseClicked(MouseEvent e) {
System.out.println("鼠标点击");
}
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下");
}
public void mouseReleased(MouseEvent e) {
System.out.println("鼠标松开");
}
public void mouseEntered(MouseEvent e) {
System.out.println("鼠标进入窗口");
}
public void mouseExited(MouseEvent e) {
System.out.println("鼠标离开窗口");
}
}
- 在
DrawPadv2
类中补全相关代码
// 获取窗口的Graphics对象
Graphics g = jf.getGraphics();
// 将Graphics对象赋值给DrawListener对象的g
dl.g = g;
为窗口添加鼠标监听器,并将窗口的图形上下文(Graphics对象)传递给DrawListener,以便后续绘制操作。
5. 在DrawListener
类中实现绘图逻辑
// 声明起始点和结束点的坐标
int x1, y1, x2, y2;
// 声明图形类型和颜色
String type = "直线";
Color color = Color.black;
@Override
public void actionPerformed(ActionEvent e) {
// 获取按钮的命令
String ac = e.getActionCommand();
System.out.println("点击了按钮:" + ac);
// 如果点击的是颜色按钮
if(ac.equals("ColorBtn")) {
// 获取按钮的背景颜色
JButton btn = (JButton) e.getSource();
color = btn.getBackground();
}
// 如果点击的是橡皮擦
else if(ac.equals("橡皮擦")) {
// 设置画笔颜色为背景色
color = new Color(238, 238, 238);
}
// 否则设置画笔颜色
else {
type = ac;
g.setColor(color);
}
}
根据按钮的命令(actionCommand),判断用户是选择了颜色、橡皮擦还是图形类型,并更新画笔颜色或绘图模式。
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("鼠标点击");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下");
// 获取鼠标按下时的坐标
x1 = e.getX();
y1 = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("鼠标松开");
// 获取鼠标松开时的坐标
x2 = e.getX();
y2 = e.getY();
// 如果y2小于80,则将y2设置为80
if(y2 < 80) {
y2 = 80;
}
// 根据图形类型绘制图形
Graphics g = DrawPanel.getGraphics();
g.setColor(color);
if (type.equals("直线")) {
g.drawLine(x1, y1, x2, y2);
} else if (type.equals("圆形")) {
g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("矩形")) {
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("实心圆形")) {
g.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("实心矩形")) {
g.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("等腰三角形")) {
// 计算等腰三角形的顶点坐标
int mx = (x1 + x2) / 2;
int my = y1;
// 绘制等腰三角形
g.drawLine(x1, y2, mx, my);
g.drawLine(mx, my, x2, y2);
g.drawLine(x1, y2, x2, y2);
} else if (type.equals("实心等腰三角形")) {
// 计算等腰三角形的顶点坐标
int mx = (x1 + x2) / 2;
int my = y1;
int h = Math.abs(y2 - y1);
int w = Math.abs(x2 - x1);
double dx = w / 2.0 / h;
// 绘制等腰三角形
for (int i = 0; i < h; i++) {
if (y1 < y2) {
g.drawLine((int) (mx - dx * i), my + i, (int) (mx + dx * i), my + i);
} else {
g.drawLine((int) (mx - dx * i), my - i, (int) (mx + dx * i), my - i);
}
}
}
}
- 在主函数中创建并显示窗口
public static void main(String[] args) {
// 创建DrawPadv2对象
DrawPadv2 dl = new DrawPadv2();
// 调用showUI方法显示UI界面
dl.showUI();
}
通过mousePressed和mouseReleased方法记录鼠标按下与释放的坐标,结合当前选择的图形类型,调用Graphics对象的绘图方法完成绘制
实现效果
最终代码
DrawPadv2
package basic.hj0507;
import javax.swing.*;
import java.awt.*;
public class DrawPadv2 {
// 创建一个DrawListener对象
DrawListener dl = new DrawListener();
// 显示UI界面
public void showUI() {
// 创建一个JFrame对象
JFrame jf = new JFrame();
// 设置窗口标题
jf.setTitle("画板v2.0");
// 设置窗口大小
jf.setSize(850,600);
// 设置窗口居中显示
jf.setLocationRelativeTo(null);
// 设置窗口关闭时的操作
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗口布局为FlowLayout
jf.setLayout(new FlowLayout());
// 定义按钮类型
String [] btnType = {"直线", "圆形", "矩形", "实心圆形", "实心矩形", "等腰三角形",
"实心等腰三角形", "橡皮擦"};
// 循环创建按钮并添加到窗口中
for(int i = 0 ; i < btnType.length ; i++) {
JButton btn = new JButton(btnType[i]);
jf.add(btn);
// 为按钮添加监听器
btn.addActionListener(dl);
}
// 定义颜色按钮的颜色
Color[] btnColors = {Color.BLACK, Color.RED, Color.GREEN,
Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGENTA,
Color.GRAY, Color.LIGHT_GRAY, Color.DARK_GRAY,
Color.PINK, Color.ORANGE, Color.WHITE};
// 循环创建颜色按钮并添加到窗口中
for(int i = 0 ; i < btnColors.length ; i++) {
JButton btn = new JButton();
// 设置按钮的命令为ColorBtn
btn.setActionCommand("ColorBtn");
// 设置按钮的背景颜色
btn.setBackground(btnColors[i]);
jf.add(btn);
// 为按钮添加监听器
btn.addActionListener(dl);
}
// 设置窗口可见
jf.setVisible(true);
// 为窗口添加鼠标监听器
jf.addMouseListener(dl);
// 获取窗口的Graphics对象
Graphics g = jf.getGraphics();
// 将Graphics对象赋值给DrawListener对象的g
dl.g = g;
}
// 主方法
public static void main(String[] args) {
// 创建DrawPadv2对象
DrawPadv2 dl = new DrawPadv2();
// 调用showUI方法显示UI界面
dl.showUI();
}
}
DrawListener
package basic.hj0507;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class DrawListener implements MouseListener, ActionListener {
// 声明Graphics对象
Graphics g;
// 声明起始点和结束点的坐标
int x1, y1, x2, y2;
// 声明图形类型和颜色
String type = "直线";
Color color = Color.black;
@Override
public void actionPerformed(ActionEvent e) {
// 获取按钮的命令
String ac = e.getActionCommand();
System.out.println("点击了按钮:" + ac);
// 如果点击的是颜色按钮
if(ac.equals("ColorBtn")) {
// 获取按钮的背景颜色
JButton btn = (JButton) e.getSource();
color = btn.getBackground();
// 设置画笔颜色
g.setColor(color);
}
// 如果点击的是橡皮擦
else if(ac.equals("橡皮擦")) {
// 设置画笔颜色为背景色
Color color2 = new Color(238,238,238);
g.setColor(color2);
}
// 否则设置画笔颜色
else {
type = ac;
g.setColor(color);
}
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("鼠标点击");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下");
// 获取鼠标按下时的坐标
x1 = e.getX();
y1 = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("鼠标松开");
// 获取鼠标松开时的坐标
x2 = e.getX();
y2 = e.getY();
// 如果y2小于80,则将y2设置为80
if(y2<80) {
y2 = 80;
}
// 根据图形类型绘制图形
if (type.equals("直线")) {
g.drawLine(x1, y1, x2, y2);
}
else if (type.equals("矩形")) {
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("圆形")) {
g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("实心矩形")) {
g.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("实心圆形")) {
g.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (type.equals("实心等腰三角形")) {
// 计算等腰三角形的顶点坐标
int mx = (x1 + x2) / 2;
int my = y1;
int h = Math.abs(y2 - y1);
int w = Math.abs(x2 - x1);
double dx = w / 2.0 / h;
// 绘制等腰三角形
for (int i = 0; i < h; i++) {
if (y1 < y2) {
g.drawLine((int) (mx - dx * i), my + i, (int) (mx + dx * i), my + i);
} else {
g.drawLine((int) (mx - dx * i), my - i, (int) (mx + dx * i), my - i);
}
}
} else if (type.equals("等腰三角形")) {
// 计算等腰三角形的顶点坐标
int mx = (x1 + x2) / 2;
int my = y1;
// 绘制等腰三角形
g.drawLine(x1, y2, mx, my);
g.drawLine(mx, my, x2, y2);
g.drawLine(x1, y2, x2, y2);
}
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("鼠标进入窗口");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("鼠标离开窗口");
}
}