事件监听机制:https://mp.csdn.net/postedit/88026952
第一部分代码:
第一个类:
package drawing223;//这是包名,copy的同学记得更改!!!!
import java.awt.Graphics;
import javax.swing.JFrame;
//定义画板类
public class DrawingFrame {
// 定义画板类初始化界面的方法
public void initUI() {
// 实例化窗体jr并设置窗体属性
// 标题
JFrame jr = new JFrame("这是一个画板!");
// 大小
jr.setSize(700, 600);
// 居中
jr.setLocationRelativeTo(null);
// 关闭
jr.setDefaultCloseOperation(3);
// 可见
jr.setVisible(true);
// 获取窗体对象jr的画笔对象gr(注意:必须在窗体界面可见之后)
Graphics gr = jr.getGraphics();
// 实例化事件接口,即事件处理类DrawingListener的对象dr
DrawingListener dr = new DrawingListener(gr);
// 给窗体对象jr添加事件监听方法addMouseListener,指定处理接口对象为dr
jr.addMouseListener(dr);
}
// 定义主函数
public static void main(String[] args) {
//实例化画板类对象dr
DrawingFrame dr = new DrawingFrame();
//调用画板类的方法
dr.initUI();
}
}
第二个类:
package drawing223;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
//实例化鼠标点击接口MouseListener,重写其中的抽象方法
public class DrawingListener implements MouseListener {
// x1,y1,x2,y2用于存储坐标值
private int x1, x2, y1, y2;
// 声明画笔对象
private Graphics gr;
// 构造函数,传参的作用,传递画笔对象
public DrawingListener(Graphics gr) {
this.gr = gr;
}
@Override
public void mouseClicked(MouseEvent arg0) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
// 按压时获取横纵坐标
x1 = arg0.getX();
y1 = arg0.getY();
}
@Override
public void mouseReleased(MouseEvent arg0) {
x2 = arg0.getX();
y2 = arg0.getY();
// 画直线方法
gr.drawLine(x1, y1, x2, y2);
}
}
执行结果:按压后释放,OK我们现在可以得到一根直线啦!
第二部分:
第一个类:
package drawing224.copy;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
//定义画板类
public class DrawingFrame {
// 定义画板类初始化界面的方法
public void initUI() {
// 实例化窗体jr并设置窗体属性
JFrame jr = new JFrame("这是一个画板!");
jr.setSize(700, 600);
jr.setLocationRelativeTo(null);
jr.setDefaultCloseOperation(3);
// 布局
FlowLayout f = new FlowLayout();
jr.setLayout(f);
// 实例化事件接口,即事件处理类DrawingListener的对象dr
// 在这里注意此时参数类型为JFrame,与第一部分参数类型不同
DrawingListener dr = new DrawingListener(jr);
// 给窗体对象jr添加事件监听方法addMouseListener,指定处理接口对象为dr
jr.addMouseListener(dr);
// 定义字符串数组
String[] str = new String[] { "直线", "矩形", "填充圆", "圆角矩形", "文字", "图片", "多边形", "立方体" };
for (int i = 0; i < str.length; i++) {
// 实例化按钮
JButton bu = new JButton(str[i]);
// 把按钮添加到界面上
jr.add(bu);
// 给按钮添加监听方法
bu.addActionListener(dr);
}
// 定义颜色类对象的数组
Color[] s = new Color[] { Color.black, Color.GREEN, Color.yellow, Color.PINK };
for (int i = 0; i < 4; i++) {
JButton bu = new JButton();
// 设置按钮的背景颜色
bu.setBackground(s[i]);
// 调整按钮的大小,在这里注意setsize方法只能用来调整顶级容器大小
bu.setPreferredSize(new Dimension(30, 30));
jr.add(bu);
bu.addActionListener(dr);
}
// 可见
jr.setVisible(true);
}
// 定义主函数,实例化画板类对象,调用初始化界面的方法
public static void main(String[] args) {
DrawingFrame df = new DrawingFrame();
df.initUI();
}
}
第二个类:
package drawing224.copy;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
//实例化鼠标点击接口MouseListener,重写其中的抽象方法
public class DrawingListener implements MouseListener, ActionListener {
//存储按下,释放,点击的坐标值
private int x1, x2, y1, y2, x3, y3;
private Color color;
private String s;
private JFrame jr;
private Graphics gr;
//标志位,默认为等待按下和释放状态
private int flag = 1;
private int lon, high;
public DrawingListener(JFrame jr) {
this.jr = jr;
}
@Override
public void actionPerformed(ActionEvent e) {
// 判断按钮类型
//字符串为空则为颜色按钮,获取背景颜色,赋值给color
if (e.getActionCommand() == "") {
JButton button = (JButton) e.getSource();
color = button.getBackground();
} else {
///不为空为形状按钮,保存按钮的文本
JButton button = (JButton) e.getSource();
s = button.getActionCommand();
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
x3 = arg0.getX();
y3 = arg0.getY();
//判断是否处于等待点击状态并对比按钮文本进行相应的画图操作
if ((flag == 2) && s.equals("多边形")) {
gr.drawLine(x2, y2, x3, y3);
x2 = x3;
y2 = y3;
if (arg0.getClickCount() == 2) {
gr.drawLine(x1, y1, x3, y3);
flag = 1;
}
} else if ((flag == 2) && s.equals("立方体")) {
if ((x3 > Math.max(x1, x2)) && (y3 < Math.min(y1, y2))) {
gr.drawLine(Math.max(x1, x2), Math.min(y1, y2), x3, y3);
gr.drawLine(Math.min(x1, x2), Math.min(y1, y2), x3 - lon, y3);
gr.drawLine(Math.max(x1, x2), Math.max(y1, y2), x3, y3 + high);
gr.drawLine(x3 - lon, y3, x3, y3);
gr.drawLine(x3, y3 + high, x3, y3);
flag = 1;
}
} else if (s.equals("文字")) {
gr.setFont(new Font("宋体", Font.BOLD, 50));
String s = new String("熊哥!");
gr.drawString(s, x1, y1);
} else if (s.equals("图片")) {
ImageIcon c = new ImageIcon("C:\\Users\\lcz\\Desktop\\666\\IMG_0456.JPG");
gr.drawImage(c.getImage(), x1, y1, 100, 100, jr);
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
System.out.println("进入");
}
@Override
public void mouseExited(MouseEvent arg0) {
System.out.println("离开");
}
@Override
public void mousePressed(MouseEvent arg0) {
// 获取窗体对象jr的画笔对象gr(注意:必须在窗体界面可见之后)
// 在此不能写作 Graphics gr = jr.getGraphics();这样会把画笔赋值给gr局部变量,后面的方法无法调用画笔
gr = jr.getGraphics();
// 给画笔上色
gr.setColor(color);
// 判断是否在按下释放状态,即flag是否等于1
if (flag == 1) {
x1 = arg0.getX();
y1 = arg0.getY();
}
}
@Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("释放");
if (flag == 1) {
x2 = arg0.getX();
y2 = arg0.getY();
}
if (s.equals("直线") && (flag == 1)) {
gr.drawLine(x1, y1, x2, y2);
} else if (s.equals("矩形") && (flag == 1)) {
gr.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (s.equals("填充圆") && (flag == 1)) {
gr.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
} else if (s.equals("圆角矩形") && (flag == 1)) {
gr.drawRoundRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1), 100, 100);
} else if (s.equals("多边形") && (flag == 1)) {
gr.drawLine(x1, y1, x2, y2);
flag = 2;
} else if (s.equals("立方体") && (flag == 1)) {
gr.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
lon = Math.abs(x2 - x1);
high = Math.abs(y2 - y1);
// 把状态设置为点击状态
flag = 2;
}
}
}
运行结果:我们可以画出来更多图形啦!
注意:
1.为什么我们需要按下释放和点击标志位?
因为鼠标的执行顺序是,按下-释放-点击,若我们不设置标志位的话,在点击操作时我们就经历了按下和释放操作,会更改前面获得的x1,y1,x2,y2的坐标为我们点击位置的坐标。
2.为什么我们在第二部分在实例化监听接口时参数变为了JFrame类?
因为我们获取画笔的代码会和实例化监听接口代码以及给按钮和界面添加监听方法的代码起冲突,为了解决冲突我们可以把JFrame类传递过来,在监听接口类中进行取画笔的相应操作。