Java简易画图工具

目录

        实现功能

        开发环境

        代码实现

                 导入包

                窗体界面(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();
    }
}

监听器

在设计窗体中添加鼠标监听器MouseListenerMouseMotionListener,创建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){

    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值