GUI画图工具的实现

文章描述了一个JavaSwing应用,该应用使用MouseListener监听鼠标的点击、按压和释放事件来绘制图形,如直线、矩形和三角形。用户可以选择不同的图形类型和颜色,程序在画布上动态更新。遇到的问题包括坐标管理、图形覆盖以及如何保存和处理鼠标事件的坐标值。
摘要由CSDN通过智能技术生成
  • 鼠标监听器MouseListener一共能监听到鼠标的5种方法。
  • 在原点按下并且释放才显示点击操作,如果按下之后移动只显示释放。
  • 所以说绘制图形只用到按下和释放两个操作
  • 在代码层面解释:释放时画线,点击时画点
  • 窗体里面坐标只能显示正数,负数在窗体外显示
  • e.getActionCommand()来获取按钮上的内容
  • 绘制矩形:g.drawRect(x, y, width, height);从左往右画,从右往左画保证起始点最小,窗体里面只能显示正数。
  • 画任意三角形bug的原因:点击的时候把按下和释放的坐标覆盖了,因为点击操作是需要按下和释放在同一个点才执行。处理方法:把按下和释放得到的坐标值想办法保存下来。
  • 怎么保存?通过标记位来保存
  • g.drawArc(x, y, width, height, startAngle, arcAngle) 绘制覆盖指定矩形的圆形或者椭圆形圆弧的轮廓。
package com.gch.drawUI;

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;
import java.util.Random;

public class DrawUI {
    // 定义坐标  窗体里坐标只能显示正数,负数在窗体外显示
    public static int x1,y1,x2,y2,x3,y3;
    // 定义字符串保存获取图形按钮上的内容
    public static String graphicsButtonName = null;
    // 标记位
    public static boolean flag = true;
    /**
       显示画图界面
     */
    public void showUI(){
        // 窗体
        JFrame win = new JFrame("画图工具");
        // 桌布,可以自适应布局
        JPanel panel = new JPanel();
        // 把桌布添加到窗体上
        win.add(panel);
        // 设置窗体大小,单位是像素
        win.setSize(800,800);
        // 设置窗体居中显示
        win.setLocationRelativeTo(null);
        // 设置退出进程
        win.setDefaultCloseOperation(3);

        // 定义字符串数组保存图形按钮名称
        String[] graphicsButton = {"直线","矩形","椭圆","等腰三角形","任意三角形","筛子"};
        // 遍历保存图形按钮的字符串数组,添加图形按钮到桌布上
        for(int i = 0;i < graphicsButton.length;i++){
            // 定义按钮添加
            JButton btn = new JButton(graphicsButton[i]);
            // 给每一个按钮添加动作监听器
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 获取图形按钮上的内容
                    graphicsButtonName = e.getActionCommand();
                }
            });
            // 把图形按钮添加到桌布上
            panel.add(btn);
        }

        // 实现类
        ColorMouse mouse = new ColorMouse();

        // 定义字符串数组保存颜色按钮的名称
        String[] colorButton = {"红色","绿色","蓝色"};
        // 定义Color数组保存对应的颜色
        Color[] color = {Color.RED,Color.GREEN,Color.blue};
        // 遍历保存颜色按钮的字符串数组,添加颜色按钮到桌布上
        for(int i  = 0;i < colorButton.length;i++){
            // 定义按钮添加
            JButton btn = new JButton(colorButton[i]);
            // 给每一个颜色按钮添加动作监听器
            btn.addActionListener(mouse); // 绑定事件处理类
            // 给每一个按钮设置背景色
            btn.setBackground(color[i]);
            // 把颜色按钮添加到桌布上
            panel.add(btn);
        }

        // 设置窗体显示可见
        win.setVisible(true);

        // 自定义内容显示在哪个组件上,画笔就从该组件上获取
        // 画笔的获取一定要放在窗体显示可见之后
        Graphics g = win.getGraphics();

        // 把画笔对象传递给ColorMouse类
        mouse.setG(g); // 引用传递/对象传递

        // 给窗体添加鼠标监听器
        win.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("点击!");
                x3 = e.getX();
                y3 = e.getY();
                if(graphicsButtonName.equals("任意三角形")){
                    g.drawLine(x1, y1, x3, y3);
                    g.drawLine(x2, y2, x3, y3);
                    flag = true;
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("按下!");
                if(flag){
                    x1 = e.getX();
                    y1 = e.getY();
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("释放!");
                if(flag){
                    x2 = e.getX();
                    y2 = e.getY();
                }
                if(graphicsButtonName.equals("直线")){
                    g.drawLine(x1,y1,x2,y2);
                }else if(graphicsButtonName.equals("矩形")){
                    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2 - x1),Math.abs(y2 - y1));
                }else if(graphicsButtonName.equals("椭圆")){
                    g.drawArc(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2 -x1),Math.abs(y2 - y1),0,360);
                }else if(graphicsButtonName.equals("等腰三角形")){
                    g.drawLine(x1, y1, x2, y2);
                    g.drawLine(x2,y2,2 * x1 - x2, y2);
                    g.drawLine(2 * x1 - x2,y2, x1, y1);
                }else if(graphicsButtonName.equals("任意三角形") && flag == true){
                    g.drawLine(x1, y1, x2, y2);
                    flag = false;
                }else if(graphicsButtonName.equals("筛子")){
                    sifter();
                }
            }
            
            /**
               画筛子
               1.随机取A B C P四个点的坐标值
               2.随机选中A B C三点中的一点,计算与P点连线的中点,并把此点画黑
             */
            public void sifter(){
                // 1.随机取A B C P四个点的坐标值
                Random r = new Random();
                int ax = r.nextInt(1000) + 1;
                int ay = r.nextInt(1000) + 1;
                int bx = r.nextInt(1000) + 1;
                int by = r.nextInt(1000) + 1;
                int cx = r.nextInt(1000) + 1;
                int cy = r.nextInt(1000) + 1;
                int px = r.nextInt(1000) + 1;
                int py = r.nextInt(1000) + 1;
                // 循环n次
                for(int i = 0;i < 100000;i++){
                    // 2.随机选中A B C三点中的一点
                    int number = r.nextInt(3) + 1;
                    // 3.计算与P点连线的中点
                    if(number == 1){ // 选中A
                        px = (ax + px) / 2;
                        py = (ay + py) / 2;
                    }else if(number == 2){ // 选中B
                        px = (bx + px) / 2;
                        py = (by + py) / 2;
                    }else if(number == 3){ // 选中C
                        px = (cx + px) / 2;
                        py = (cy + py) / 2;
                    }
                    // 4.并把此点画黑
                    g.drawLine(px, py, px, py);
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("进入!");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("退出!");
            }
        });
    }
}
package com.gch.drawUI;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
   事件处理类
 */
public class ColorMouse implements ActionListener {
    private Graphics g; // 保存传递过来的画笔对象
    public void setG(Graphics g) {
        this.g = g;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // 定义字符串保存获取颜色按钮上的内容
        String colorButtonName = e.getActionCommand();
        if(colorButtonName.equals("红色")){
            g.setColor(Color.RED);
        }else if(colorButtonName.equals("绿色")){
            g.setColor(Color.green);
        }else if(colorButtonName.equals("蓝色")){
            g.setColor(Color.blue);
        }
    }
}
package com.gch.drawUI;

public class Manage {
    /**
       主函数
     */
    public static void main(String[] args) {
        DrawUI ui = new DrawUI();
        ui.showUI();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GaoSSR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值