用java的事件监听机制实现一个简单的画板应用:通过选择图形按钮和颜色按钮来画出自己想画的图形:直线、空心矩形、圆形、折线、多边形、圆角矩形、弧线、曲线、喷枪
今天做一个简单的画板,完整代码附在文章末尾处。
- 功能:通过选择图形按钮和颜色按钮来画出自己想画的图形。
- 界面展示:
- 思路:
1.做一个可视化界面:创建JFrame对象,并设置Title、Size、Layout等基本属性。
2.将鼠标监听器MouseListener,MouseMotionListener绑定在JFrame对象上,方便我们监听到鼠标在窗体上的操作。
3.获取一个画笔来画出图形。
4.添加JButton等控件并设置属性。
5.将动作监听器ActionListener绑定在JButton对象上,可以在点击按钮后确定绘制的图形形状和颜色
6.从监听中获取我们画图所需要的数据。
第一步:我们实现可视化界面,创建JFrame对象,并设置Title、Size、Layout等基本属性。
import javax.swing.*;
import java.awt.*;public class UI {public void initUI(){//JFrame不是自己写的类,是java源码中的窗体类//使用其他包中的类,需要导入这个类所在的包路径//创建窗体对象JFrame jf=new JFrame();//设置窗体对象的属性jf.setTitle("画图板V1.0");jf.setSize(800,800);//点击关闭按钮之后需要执行的操作jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //可视化jf.setVisible(true); }public static void main(String[] args) {UI ui=new UI();ui.initUI();}
}
第二步:将鼠标监听器MouseListener,MouseMotionListener绑定在JFrame对象上,在代码中体现为:
1.创建一个类实现监听器接口,重写所有方法
2.给具体的控件设置对应的监听器对象
实现鼠标监听器接口代码如下:
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;public class DrawListener implements MouseListener,MouseMotionListener{ //Alt+Enter@Overridepublic void mouseClicked(MouseEvent e) {//加上动作被监听之后想要执行的代码System.out.println("mouseClicked");}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("mousePressed");}@Overridepublic void mouseReleased(MouseEvent e) {System.out.println ("mouseReleased");}@Overridepublic void mouseEntered(MouseEvent e) {System.out.println ("mouseEntered");}@Overridepublic void mouseExited(MouseEvent e) {System.out.println ("mouseExited");}@Overridepublic void mouseMoved(MouseEvent e) {}@Overridepublic void mouseDragged(MouseEvent e) {}
}
我们在可视化操作后加上这几行代码,实现鼠标的监听
//创建DrawListener的对象DrawListener dl=new DrawListener();//将监听器对象绑定到窗体对象上jf.addMouseListener(dl);jf.addMouseMotionListener(dl);
第三步:获取一个画笔来画出图形。
1.获取Graphics
2.将Graphics对象g传入监听器对象中
3.在MouseListener监听器对应的方法中,用Graphics对象g画图
首先获取Graphics:
Graphics g=jf.getGraphics();
- Graphics是一个可视化组件,所以必须在组件可视化之后才可以获取;
- Graphics不能直接创建对象,需要从所需要绘制的组件(此例为窗体)上用getGraphics方式获取
然后将Graphics对象g传入监听器对象中:
(1).在监听器中声明一个Graphics类型的属性对象变量名
public class DrawListener implements MouseListener, ActionListener {
Graphics gr=null;
}
(2). 用监听器对象调用这个属性变量名来“赋值”=被获取的Graphics对象
dl.gr=g;
- g应该在哪里使用?我们举个例子,比如说绘制直线,应该在鼠标释放之后,使用g绘制一根直线
第四步:添加JButton等控件并设置属性。
如果需要考虑在窗体上加载其他组件(按钮、输入框),就需要先设置好布局规则,此处我们用到的是边界布局:
//边界布局//创建面板对象JPanel bt1=new JPanel();JPanel bt2=new JPanel();JPanel bt3=new JPanel();//把bt1,bt2,bt3 上-中-下的方法分配jf.add(bt1,BorderLayout.NORTH);jf.add(bt2,BorderLayout.CENTER);jf.add(bt3,BorderLayout.SOUTH);
接下来我们通过数组给窗体添加按钮:
String[] shape = {"直线", "空心矩形", "圆形", "折线","多边形","圆角矩形","弧线","曲线","喷枪","橡皮擦","清除"};for (int i = 0; i < shape.length; i++) {//创建按钮对象JButton btn = new JButton(shape[i]);//将按钮加载到窗体上bt1.add(btn);}Color[] color={Color.RED,Color.GREEN,Color.BLUE,Color.black,Color.MAGENTA,Color.yellow,Color.PINK,Color.CYAN};String[] colorName={"红色","绿色","蓝色","黑色","粉色","黄色","粉色","蓝色"};for (int i = 0; i < colorName.length; i++) {JButton bttn = new JButton(colorName[i]);bt3.add(bttn);bttn.setBackground(color[i]);bttn.setForeground(color[i]);}
第五步:将动作监听器ActionListener绑定在JButton对象上,在代码中体现为:
1.创建一个类实现监听器ActionListener接口,重写所有方法
2.给具体的控件设置对应的监听器对象
由于可以实现多个接口,所以我们在原基础上添加ActionListener即可。
public class DrawListener implements MouseListener, ActionListener { @Overridepublic void actionPerformed(ActionEvent e) {//被监听的按钮被点击时调用System.out.println ("按钮被点击了");}
同样的,将按钮监听器绑定到对象窗口上
String[] shape = {"直线", "空心矩形","圆形", "折线","多边形","圆角矩形","弧线","曲线","喷枪","橡皮擦","清除"};for (int i = 0; i < shape.length; i++) {//将监听器对象绑定到按钮对象上btn.addActionListener(dl);}Color[] color={Color.RED,Color.GREEN,Color.BLUE,Color.black,Color.MAGENTA,Color.yellow,Color.PINK,Color.CYAN};String[] colorName={"红色","绿色","蓝色","黑色","粉色","黄色","粉色","蓝色"};for (int i = 0; i < colorName.length; i++) {bttn.addActionListener(dl);}
第六步:从监听中获取画图所需要的数据
1.获取按钮上的文本和按钮的背景颜色
2.获取鼠标操作时的相关坐标
首先获取按钮上的文本:
要实现“点击对应按钮才能绘制”这个功能,我们需要加入一个判断语句。
我们先来声明一个图形种类的字符串
public class DrawListener implements MouseListener, ActionListener { //Alt+EnterString shapeType="";}
然后我们获取按钮上的文本并赋值给图形种类
@Overridepublic void actionPerformed(ActionEvent e) {//获取按钮上的文本String btnser = e.getActionCommand();//被监听的按钮,被点击时调用System.out.println (btnser+"按钮被点击了");shapeType=btnser;}
接着我们获取按钮的背景颜色:
@Overridepublic void actionPerformed(ActionEvent e) {//获取按钮上的文本String btnser = e.getActionCommand();if(btnser.contains("色")){//获取当前的事件源对象JButton jbu=(JButton)e.getSource();Color color=jbu.getBackground();gr.setColor(color);}else{shapeType=btnser;System.out.println();}}
接着获取鼠标操作时的相关坐标,因为只有知道坐标才可以绘制图形 :
public void mousePressed(MouseEvent e) {//获取坐标int x=e.getX();int y=e.getY();System.out.println ("mousePressed x="+x+" y="+y);}
最后我们回到 mouseReleased这里,准备绘制图形。
由于直线、椭圆、矩形等有现成的绘制方法可以调用,因此比较简单:
@Overridepublic void mouseReleased(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (shapeType.equals("直线")) {gr.drawLine(x1, y1, x2, y2);gr.drawPolyline(new int[]{50, 100, 150}, new int[]{50, 100, 50}, 3);} else if (shapeType.equals("空心矩形")) {// 左上角的坐标 宽 高gr.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));} else if (shapeType.equals("圆形")) {//圆的外切矩形gr.drawOval(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));} else if (shapeType.equals("圆角矩形")) {gr.drawRoundRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1), 15, 15);} else if (shapeType.equals("弧线")) {gr.drawArc(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1), 15, 180);}}
接下来我们画折线,折线难点在于:如何存储多个点的坐标;将多个点连线的判断条件是什么
折线代码如下:
@Overridepublic void actionPerformed(ActionEvent e) {if (btnser.equals("折线")) {if (!polyLineFlag) {polyLineFlag = true;} else {gr.drawPolyline(polyLineX, polyLineY, index);index = 0;}}else{polyLineFlag = false;index=0;}
@Overridepublic void mouseReleased(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (shapeType.equals("折线")) {polyLineX[index] = x2;polyLineY[index++] = y2;}}
多边形的代码可以参考折线,只要调用方法:drawPolygon(先画点再连线)即可。
这边我们用另一种思路来绘制多边形:先画直线后封口。难点在于记录第一个点的坐标和确定封口条件:
@Overridepublic void actionPerformed(ActionEvent e) {if(btnser.equals("多边形")){if (!polyFlag) {polyFlag = true;} else {gr.drawLine(x0, y0, x2, y2);a=-1;}}else{polyFlag = false;a=-1;}}
@Overridepublic void mousePressed(MouseEvent e) {//获取坐标x1 = e.getX();y1 = e.getY();if(a<0&&shapeType.equals("多边形")){x0=x1;y0=y1;a=1;}}
@Overridepublic void mouseReleased(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (shapeType.equals("多边形")) {gr.drawLine(x1, y1, x2, y2);}}
曲线、喷枪、橡皮擦的实现需要用到 mouseDragged方法:
@Overridepublic void mouseDragged(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (shapeType.equals("曲线")) {gr.drawLine(x1, y1, x2, y2);x1 = x2;y1 = y2;} else if (shapeType.equals("喷枪")) {for (int k = 0; k < 10; k++) {Random i = new Random();int a = i.nextInt(8);int b = i.nextInt(10);gr.drawLine(x2 + a, y2 + b, x2 + a, y2 + b);}} else if (shapeType.equals("橡皮擦")) {gr.clearRect(x2, y2, 10, 10);}}
完整代码附上:
import javax.swing.*;
import java.awt.*;public class UI{public void initUI() {//JFrame不是自己写的类,是java源码中的类//创建窗体对象JFrame jf = new JFrame();//设置窗体对象的属性jf.setTitle("画图板");jf.setSize(1000, 600);//点击关闭按钮之后需要执行的操作jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//边界布局//创建面板对象JPanel bt1=new JPanel();JPanel bt2=new JPanel();JPanel bt3=new JPanel();//把bt1,bt2,bt3 上-中-下的方法分配jf.add(bt1,BorderLayout.NORTH);jf.add(bt2,BorderLayout.CENTER);jf.add(bt3,BorderLayout.SOUTH);bt1.setBackground(Color.white);bt2.setBackground(Color.white);bt3.setBackground(Color.white);jf.setBackground(Color.white);//创建DrawListener的对象DrawListener dl = new DrawListener();//将监听器对象绑定到窗体对象上jf.addMouseListener(dl);jf.addMouseMotionListener(dl);String[] shape = {"直线", "空心矩形", "圆形", "折线","多边形","圆角矩形","弧线","曲线","喷枪","橡皮擦","清除"};for (int i = 0; i < shape.length; i++) {//创建按钮对象JButton btn = new JButton(shape[i]);//将按钮加载到窗体上bt1.add(btn);//将监听器对象绑定到按钮对象上btn.addActionListener(dl);}Color[] color={Color.RED,Color.GREEN,Color.BLUE,Color.black,Color.MAGENTA,Color.yellow,Color.PINK,Color.CYAN};String[] colorName={"红色","绿色","蓝色","黑色","粉色","黄色","粉色","蓝色"};for (int i = 0; i < colorName.length; i++) {JButton bttn = new JButton(colorName[i]);bt3.add(bttn);bttn.setBackground(color[i]);bttn.setForeground(color[i]);bttn.addActionListener(dl);}//将所有组件添加完成之后再可视化jf.setVisible(true);//获取Graphics//因为Graphics是一个可视化组件,所以必须可视化之后才能获取Graphics g= jf.getGraphics();//将Graphics对象传入监听器对象中//1. 在监听器中声明一个Graphics类型的属性对象变量名;//2. 监听器对象调用这个属性变量名来“赋值”=这边获取Graphics对象dl.gr=(Graphics2D) g;dl.jFrame = jf;}public static void main(String[] args) {UI ui=new UI();ui.initUI();}}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;public class DrawListener implements MouseListener, ActionListener, MouseMotionListener {Graphics2D gr = null;String shapeType = "";int x0,y0,x1,y1, x2, y2,a=-1;//折线坐标数组int[] polyLineX = new int[100], polyLineY = new int[100];int index = 0; //点的个数boolean polyLineFlag = false; //false点点 true连线boolean polyFlag = false; //false画直线 true封尾JFrame jFrame;@Overridepublic void actionPerformed(ActionEvent e) {String btnser = e.getActionCommand();System.out.println(btnser + "按钮被点击了");if (btnser.contains("色")) {JButton jbu = (JButton) e.getSource();Color color = jbu.getBackground();gr.setColor(color);} else {shapeType = btnser;}if (btnser.equals("折线")) {if (!polyLineFlag) {polyLineFlag = true;} else {gr.drawPolyline(polyLineX, polyLineY, index);index = 0;}}else{polyLineFlag = false;index=0;}if(btnser.equals("多边形")){if (!polyFlag) {polyFlag = true;} else {gr.drawLine(x0, y0, x2, y2);a=-1;}}else{polyFlag = false;a=-1;}if (shapeType.equals("清除")) {// 左上角的坐标 宽 高jFrame.repaint();}}@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {//获取坐标x1 = e.getX();y1 = e.getY();if(a<0&&shapeType.equals("多边形")){x0=x1;y0=y1;a=1;}}@Overridepublic void mouseReleased(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (y2 < 65)return;if (shapeType.equals("直线")) {gr.drawLine(x1, y1, x2, y2);gr.drawPolyline(new int[]{50, 100, 150}, new int[]{50, 100, 50}, 3);} else if (shapeType.equals("空心矩形")) {gr.drawRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));} else if (shapeType.equals("圆形")) {gr.drawOval(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1));} else if (shapeType.equals("圆角矩形")) {gr.drawRoundRect(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1), 15, 15);} else if (shapeType.equals("弧线")) {gr.drawArc(x1, y1, Math.abs(x2 - x1), Math.abs(y2 - y1), 15, 180);} else if (shapeType.equals("折线")) {polyLineX[index] = x2;polyLineY[index++] = y2;}else if (shapeType.equals("多边形")) {gr.drawLine(x1, y1, x2, y2);}}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}@Overridepublic void mouseDragged(MouseEvent e) {x2 = e.getX();y2 = e.getY();if (y2 < 65)return;if (shapeType.equals("曲线")) {gr.drawLine(x1, y1, x2, y2);x1 = x2;y1 = y2;} else if (shapeType.equals("喷枪")) {for (int k = 0; k < 10; k++) {Random i = new Random();int a = i.nextInt(8);int b = i.nextInt(10);gr.drawLine(x2 + a, y2 + b, x2 + a, y2 + b);}} else if (shapeType.equals("橡皮擦")) {gr.clearRect(x2, y2, 10, 10);}}@Overridepublic void mouseMoved(MouseEvent e) {}
}
用java的事件监听机制实现一个简单的画板应用:通过选择图形按钮和颜色按钮来画出自己想画的图形:直线、空心矩形、圆形、折线、多边形、圆角矩形、弧线、曲线、喷枪相关推荐
- Java中事件监听机制
Java中事件监听机制 一.事件监听机制的定义 要想了解Java中的事件监听机制,首先就要去了解一下在Java中事件是怎样去定义的呢!在使用Java编写好一个界面后,我们就会对界面进行一些操作,比如, ...
- java监听机制_详解java的事件监听机制和观察者设计模式
首先说说监听器: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执 行. java的事件监 ...
- java监听com口_简单了解Java接口+事件监听机制
1.接口: 定义方法: public interface interName //extends interName2, interName3...可继承多个接口 在接口里只能定义常量和抽象方法. p ...
- springBoot启动事件监听机制
springBoot启动之事件监听机制源码解析 1. Java的事件监听机制 在进行正式的分析之前,先介绍一下Java的事件监听机制.参考05–SpringBoot启动之事件监听机制 Java事件监听 ...
- Spring容器的事件监听机制(简单明了的介绍)
文章目录 前言 事件 1. 定义事件 2. 定义监听器 3. 定义发布器 Spring容器的事件监听机制 1.事件的继承类图 监听器的继承类图 总结 前言 上一篇我们介绍了SpringFactorie ...
- java中事件监听_Java中的事件监听机制
鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...
- java swing事件监听_Java swing(awt):事件监听机制的实现原理+简单示例
(1)实现原理 事件监听机制的实现: 参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回 ...
- 4.JAVA之GUI编程事件监听机制
事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...
- java事件监听机制pdf,事件监听机制(转)
事件监听机制在java编程中有很重要的应用,一般我们在处理GUI编程时,只是重写一下监听接口的perform函数即可.但事件监听在底层是如何运行的?通过下面的例子我们可以有个清楚地了解. 1. ...
最新文章
- 【转】iOS开发学习计划
- 如何在JavaScript中实现堆栈和队列?
- python与excel做数据可视化-python做可视化数据分析,究竟怎么样?
- 神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(Matplotlib绘图基础<1>python)
- 必须使用初始化列表的情况
- 在Centos7 更改Docker默认镜像和容器的位置
- Java 多线程基本概念
- 浅谈细说 JS 函数(call,apply,重载)
- 2018年北京市POI数据各类型POI
- 线性表之带头双向循环链表
- PES,TS,PS,RTP等流的打包格式解析之PES流
- limbo模拟器运行linux,Limbowin10镜像下载|Limbo模拟器win10镜像 可上网版_最火软件站...
- 被哈佛录取后,他骑行4300公里旅行回家
- 学生抖音宣传母校被吐槽“招生减章”,网友:哈哈哈哈哈哈
- 基于Docker搭建DzzOffice与OnlyOffice线上协同办公服务器
- 电子商务企业如何把握大数据?
- 1 Tensorflow - 30行代码搞定手写识别
- JS学习笔记之面向对象 5.3
- 34函数单调性与极值
- IBM 客户拜访模式及特色销售方法简介