目录
实现功能
开发环境
代码实现
导入包
窗体界面(DrawUI)
监听器
实现监听器功能(DrawMouse)
addActionListener监听器
1. 曲线
2.直线
3.长方形
4.等腰三角形
5.三角形
6.多边形
最终效果
完整代码
实现功能
画曲线、直线、长方形、等腰三角形、三角形、多边形,以及切换画笔颜色
开发环境
开发语言Java,开发工具IDEA,jdk18
代码实现
主要分为两个板块实现,分别为设计界面(DrawUI)和鼠标监听器(DrawMouse)
完整代码在结尾
导入包
//DrawUI.java
import javax.swing.*;
import java.awt.*;
//DrawMouse.java
import java.awt.event.*;
窗体界面(DrawUI)
通过JFrame设计窗体,窗体内用JPanel组件创建容器,容器用BorderLayout布局,north部分为功能区,即可选择图形、颜色按钮;剩下部分为画图区;按钮通过ActionListener监听器实现功能,其中颜色按钮以背景区分颜色功能
//DrawUI
package draw;
import javax.swing.*;
import java.awt.*;
public class DrawUI {
//1.显示画图界面
public void initUI(){
JFrame jf = new JFrame();
jf.setSize(900,900);
jf.setTitle("画图工具");
jf.setDefaultCloseOperation(3); //退出进程
jf.setLocationRelativeTo(null); //居中显示
jf.setLayout(new BorderLayout());
//JPanel组件容器
JPanel north = new JPanel();
north.setBackground(Color.BLUE);
north.setPreferredSize(new Dimension(0,40)); //默认宽度为窗体宽度,可设置为0
jf.add(north,BorderLayout.NORTH);
//画图区
JPanel drawPanel = new JPanel();
drawPanel.setBackground(Color.WHITE);
jf.add(drawPanel,BorderLayout.CENTER);
//设置可见
jf.setVisible(true);
//3.画笔:自定义内容显示在哪个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象,一定要在窗体显示可见之后
Graphics g = drawPanel.getGraphics();
//通过数组设置按钮
//图形按钮
String[] arrary = {"曲线","直线","长方形","等腰三角形","三角形","多边形"};
for (int i = 0; i < arrary.length; i++) {
JButton jbu = new JButton(arrary[i]);
north.add(jbu);
jbu.addActionListener(mouse);
}
//颜色按钮
Color[] color = {Color.RED,Color.GREEN,Color.BLUE,Color.MAGENTA};
for (int i=0;i<color.length;i++){
JButton but = new JButton();
but.setBackground(color[i]);
but.setPreferredSize(new Dimension(30,30));
north.add(but);
but.addActionListener(mouse);
}
}
public static void main(String[] args) {
DrawUI ui = new DrawUI();
ui.initUI();
}
}
监听器
在设计窗体中添加鼠标监听器MouseListener和MouseMotionListener,创建DrawMouse.java并将画笔和窗体传入该类中
//监听器
//a.事件源:当前动作所发生的组件(swing)
//b.监听器:鼠标监听器方法:addMouseListener()
//c.绑定事件处理类
//2.给窗体添加鼠标监听器方法
DrawMouse mouse = new DrawMouse();
drawPanel.addMouseListener(mouse);
drawPanel.addMouseMotionListener(mouse);
//把对象传递给DrawMouse类
mouse.gr = g;
mouse.jf = jf;
实现监听器功能(DrawMouse)
创建对象
//引用传递
//保存传递过来的画笔对象
public Graphics gr;
//坐标
public int x1,y1,x2,y2,x3,y3,x4,y4;
public int w,h,min1,min2,max2,z;
public JFrame jf;
//按钮名字
public String name;
public int i=1;
//传递颜色
public Color col;
addActionListener监听器
通过getSource()方法判断按钮内容来辨别该按钮为图形按钮还是颜色按钮,若按钮内容不为空即为图形按钮,反之为颜色按钮;同时通过颜色按钮的背景颜色来设置画笔颜色,实现颜色选择功能
public void actionPerformed(ActionEvent e){
JButton button = (JButton) e.getSource();
//判断按钮为图形按钮或是颜色按钮
if (button.getActionCommand() != "") {
name = e.getActionCommand();
}else{
col = button.getBackground();
gr.setColor(col);
}
}
1. 曲线
曲线功能通过MouseMotionListener监听器中的mouseDragged方法实现,实际上就是无数段线段组成曲线。x1,y1为起点,x2,y2为拖动坐标,连接两点后将x2,y2坐标赋值给x1,y1,以此类推实现曲线功能
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseDragged(MouseEvent e){
if("曲线".equals(name)){
x2=e.getX();
y2=e.getY();
gr.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
2.直线
确定起点、终点后连接两点
这里mouseDragged()方法的拖动是通过画无数条与背景同色的线来实现,不推荐使用
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
//绘制直线
if ("直线".equals(name)){
gr.drawLine(x1,y1,x2,y2);
}
}
public void mouseDragged(MouseEvent e){
if ("直线".equals(name)){
//设置拖动效果
gr.setColor(Color.WHITE);
gr.drawLine(x1,y1,x4,y4);
x4 = e.getX();
y4 = e.getY();
gr.setColor(col);
gr.drawLine(x1,y1,x4,y4);
}
}
3.长方形
通过drawRect()方法,参数为drawRect(int x,int y,int width,int height),首先要确定的是坐标,若直接选择x1和y1会发现若两坐标为负(以鼠标初次按下为准),长方形会画不出来,所以需要定义x坐标的最小值min1和y的最小值min2来确定矩形的左上角,w和h作为矩形的长和宽,所以矩形的四个参数就确定了:min1,min2,w,h
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
//比较坐标大小,min1和min2分别取为x、y的最小值,max2为取y的最大值
int[] arr1 = {x1,x2};
min1 = arr1[0];
for (int i=1;i<arr1.length;i++){
if (arr1[i]<min1){
min1 = arr1[i];
}
}
int[] arr2 = {y1,y2};
min2 = arr2[0];
max2 = arr2[0];
for (int i=1;i<arr2.length;i++){
if (arr2[i]<min2){
min2 = arr2[i];
}else {
max2 = arr2[i];
}
}
//绝对值
w = Math.abs(x1-x2);
h = Math.abs(y1-y2);
//绘制长方形
if ("长方形".equals(name) ) {
gr.drawRect(min1, min2, w, h);
}
}
4.等腰三角形
等腰三角形将三个点连成线即可,分别是左下角和右下角的点以及三角形的顶点,前面两点和长方形类似,顶点的x坐标设为z,y坐标即y1、y2选最大值
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
//比较坐标大小,min1和min2分别取为x、y的最小值,max2为取y的最大值
int[] arr1 = {x1,x2};
min1 = arr1[0];
for (int i=1;i<arr1.length;i++){
if (arr1[i]<min1){
min1 = arr1[i];
}
}
int[] arr2 = {y1,y2};
min2 = arr2[0];
max2 = arr2[0];
for (int i=1;i<arr2.length;i++){
if (arr2[i]<min2){
min2 = arr2[i];
}else {
max2 = arr2[i];
}
}
//绝对值
w = Math.abs(x1-x2);
h = Math.abs(y1-y2);
//等腰三角形顶点x坐标
z = Math.abs(x2-x1)/2+min1;
if ("等腰三角形".equals(name)){
x2 = e.getX();
y2 = e.getY();
gr.drawLine(x1,max2,x2,max2);
gr.drawLine(z,min2,x1,max2);
gr.drawLine(z,min2,x2,max2);
}
}
5.三角形
先确定一条直线,在确定一个点,连接线段两端即画出三角形。
这里需要注意一个地方,当你画完一条线后发现确定点时无法连接线的两端,通过输出发现点击时出现“按下 松开 点击”
这是因为在mouseClicked监听器中会默认执行“按下”和“松开”,会画出一条类似于点的线,所以无法与线段连接。这里需要设定一个i来判断这两个状态,i的初始值为1,当i=1时获取x1,y1,x2,y2,画线后执行i++,确定点后再将i重新赋值为1,这样就可以继续画下一个三角形
public void mouseClicked(MouseEvent e){
System.out.println("点击");
if ("三角形".equals(name)){
x3 = e.getX();
y3 = e.getY();
gr.drawLine(x1,y1,x3,y3);
gr.drawLine(x2,y2,x3,y3);
i=1;
}
}
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
if ("三角形".equals(name)){
gr.drawLine(x1,y1,x2,y2);
i++;
}
}
6.多边形
类似三角形,先确定一条线,然后点击画布会将这个点与x2,y2连接,以此类推。此处i的用法与三角形一致
public void mouseClicked(MouseEvent e){
System.out.println("点击");
if ("多边形".equals(name)){
x3 = e.getX();
y3 = e.getY();
gr.setColor(col);
gr.drawLine(x2,y2,x3,y3);
//将坐标更新为下一次点击位置
x2=x3;
y2=y3;
if(e.getClickCount() == 2){
gr.drawLine(x1,y1,x2,y2);
i=1;
}
}
}
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
if ("多边形".equals(name) && i==1){
gr.drawLine(x1,y1,x2,y2);
i++;
}
}
最终效果
完整代码
DrawUI.java
import javax.swing.*;
import java.awt.*;
public class DrawUI {
//1.显示画图界面
public void initUI(){
JFrame jf = new JFrame();
jf.setSize(900,900);
jf.setTitle("画图工具");
jf.setDefaultCloseOperation(3); //退出进程
jf.setLocationRelativeTo(null); //居中显示
jf.setLayout(new BorderLayout());
//流式布局管理器
//FlowLayout flow = new FlowLayout();
//jf.setLayout(flow);
//JPanel组件容器
JPanel north = new JPanel();
north.setBackground(Color.BLUE);
north.setPreferredSize(new Dimension(0,40)); //默认宽度为窗体宽度,可设置为0
jf.add(north,BorderLayout.NORTH);
//画图区
JPanel drawPanel = new JPanel();
drawPanel.setBackground(Color.WHITE);
jf.add(drawPanel,BorderLayout.CENTER);
//设置可见
jf.setVisible(true);
//3.画笔:自定义内容显示在哪个组件上,画笔就从该组件上获取
//从窗体上获取画笔对象,一定要在窗体显示可见之后
Graphics g = drawPanel.getGraphics();
//监听器
//a.事件源:当前动作所发生的组件(swing)
//b.监听器:鼠标监听器方法:addMouseListener()
//c.绑定事件处理类
//2.给窗体添加鼠标监听器方法
DrawMouse mouse = new DrawMouse();
drawPanel.addMouseListener(mouse);
drawPanel.addMouseMotionListener(mouse);
//通过数组设置按钮
String[] arrary = {"曲线","直线","长方形","等腰三角形","三角形","多边形"};
for (int i = 0; i < arrary.length; i++) {
JButton jbu = new JButton(arrary[i]);
north.add(jbu);
jbu.addActionListener(mouse);
}
Color[] color = {Color.RED,Color.GREEN,Color.BLUE,Color.MAGENTA};
for (int i=0;i<color.length;i++){
JButton but = new JButton();
but.setBackground(color[i]);
but.setPreferredSize(new Dimension(30,30));
north.add(but);
but.addActionListener(mouse);
}
//把画笔对象传递给DrawMouse类
mouse.gr = g;
mouse.jf = jf;
}
public static void main(String[] args) {
DrawUI ui = new DrawUI();
ui.initUI();
}
}
DrawMouse.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
//事件处理类
//继承接口:implements
//继承接口一定要重写接口中所有的抽象方法
public class DrawMouse implements MouseListener,ActionListener,MouseMotionListener{
//引用传递
//保存传递过来的画笔对象
public Graphics gr;
public int x1,y1,x2,y2,x3,y3,x4,y4;
public int w,h,min1,min2,max2,z;
public JFrame jf;
//按钮名字
public String name;
public int i=1;
//传递颜色
public Color col;
public void mouseClicked(MouseEvent e){
System.out.println("点击");
if ("三角形".equals(name)){
x3 = e.getX();
y3 = e.getY();
gr.drawLine(x1,y1,x3,y3);
gr.drawLine(x2,y2,x3,y3);
i=1;
}
if ("多边形".equals(name)){
x3 = e.getX();
y3 = e.getY();
gr.setColor(col);
gr.drawLine(x2,y2,x3,y3);
//将坐标更新为下一次点击位置
x2=x3;
y2=y3;
if(e.getClickCount() == 2){
gr.drawLine(x1,y1,x2,y2);
i=1;
}
}
}
public void mousePressed(MouseEvent e){
System.out.println("按下");
//获取当前坐标值
if (i==1) {
x1 = e.getX();
y1 = e.getY();
}
}
public void mouseReleased(MouseEvent e){
System.out.println("松开");
//获取坐标
if (i==1 ) {
x2 = e.getX();
y2 = e.getY();
}
//比较坐标大小,min1和min2分别取为x、y的最小值,max2为取y的最大值
int[] arr1 = {x1,x2};
min1 = arr1[0];
for (int i=1;i<arr1.length;i++){
if (arr1[i]<min1){
min1 = arr1[i];
}
}
int[] arr2 = {y1,y2};
min2 = arr2[0];
max2 = arr2[0];
for (int i=1;i<arr2.length;i++){
if (arr2[i]<min2){
min2 = arr2[i];
}else {
max2 = arr2[i];
}
}
//绝对值
w = Math.abs(x1-x2);
h = Math.abs(y1-y2);
//等腰三角形顶点x坐标
z = Math.abs(x2-x1)/2+min1;
//绘制直线
if ("直线".equals(name)){
gr.drawLine(x1,y1,x2,y2);
}
//绘制长方形
if ("长方形".equals(name) ) {
gr.drawRect(min1, min2, w, h);
}
//绘制三角形
if ("等腰三角形".equals(name)){
x2 = e.getX();
y2 = e.getY();
gr.drawLine(x1,max2,x2,max2);
gr.drawLine(z,min2,x1,max2);
gr.drawLine(z,min2,x2,max2);
}
if ("三角形".equals(name)){
gr.drawLine(x1,y1,x2,y2);
i++;
}
if ("多边形".equals(name) && i==1){
gr.drawLine(x1,y1,x2,y2);
i++;
}
}
public void actionPerformed(ActionEvent e){
JButton button = (JButton) e.getSource();
//判断按钮为图形按钮或是颜色按钮
if (button.getActionCommand() != "") {
name = e.getActionCommand();
}else{
col = button.getBackground();
gr.setColor(col);
}
}
public void mouseDragged(MouseEvent e){
if("曲线".equals(name)){
x2=e.getX();
y2=e.getY();
gr.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
if ("直线".equals(name)){
//设置拖动效果
gr.setColor(Color.WHITE);
gr.drawLine(x1,y1,x4,y4);
x4 = e.getX();
y4 = e.getY();
gr.setColor(col);
gr.drawLine(x1,y1,x4,y4);
}
}
public void mouseMoved(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
}