zoukankan      html  css  js  c++  java
  • Java小项目——画板

    一、项目设计

    1、界面设计JFrame

    上面为控制栏JPanel

    下面为绘制面板JPanel

    2、基本思路

    鼠标事件监听器:展示一个JPanel界面,添加鼠标事件监听器,记录鼠标点击事件的坐标;

    getGraphics()方法:可以得到java.awt.Graphics对象gr,gr作为“画笔”,调用draw方法并传入坐标,可以绘制相应图像。

    3、具体功能

    3.1、绘制方式:

    画直线:

    g.drawLine(x1,y1,x2,y2);
    

    画矩形:

    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
    

    画多边形:

    若为第一次单击,保存该坐标;非第一次单击,绘制两个单击之间的直线;双击后,绘制第一次单击和本次双击坐标之间的直线,再清空所有坐标。

    拖动绘制:

    拖动鼠标中,不断绘制两个时间段之间两点之间的直线。

    3.2、颜色选取

    可以选取对应颜色进行绘制

    3.3、重绘

    改变窗体大小时,会调用paint()函数,重绘。

    需要在这个函数中,写重绘已经绘制的图形的代码,用于保存代码。

    二、初步实现:界面实现+绘制直线

    1、主函数部分:SampleDraw类

    package Draw;
    
    import javax.swing.*;
    import java.awt.*;
    
    public class SampleDraw {
        public static void main(String args[]){
            SampleDraw draw = new SampleDraw();
            draw.showUI();
        }
    
        public void showUI(){
    //主界面JFrame jf
            JFrame jf = new JFrame();
            jf.setTitle("画图1.0");
            jf.setSize(800,800);
            jf.setLocationRelativeTo(null);
            jf.setDefaultCloseOperation(3);
            
            //控制台JPanel jp1+绘制界面JPanel jp2
            JPanel jp1 = new JPanel();
            JPanel jp2 = new JPanel();
            jp1.setBackground(java.awt.Color.white);
            jf.add(jp1,BorderLayout.NORTH);
            jf.add(jp2,BorderLayout.CENTER);
            
            //按钮:前四个为绘制功能;后两个为颜色选择
            JButton jb1 = new JButton("线条");
            JButton jb2 = new JButton("矩形");
            JButton jb3 = new JButton("多边形");
            JButton jb4 = new JButton("绘制");
            JButton jbc1 = new JButton("蓝色");
            JButton jbc2 = new JButton("绿色");
            jbc1.setForeground(Color.blue);
            jbc2.setForeground(Color.green);
            //jbc2.setBackground(Color.BLACK);
            jp1.add(jb1);
            jp1.add(jb2);
            jp1.add(jb3);
            jp1.add(jb4);
            jp1.add(jbc1);
            jp1.add(jbc2);
    
            //可见放在add之后,获取之前
            jf.setVisible(true);
    
            //创建画笔对象gr,添加至jpanel2
            Graphics gr = jp2.getGraphics();
            
            //鼠标监听器对象mouse
            //构造函数初始化:使得鼠标中的位置,获取画布类:鼠标在画布上画线、多边形
            addMouseListener mouse = new addMouseListener(gr);
            
            //在各个事件源(组件)上添加鼠标监听器
            jp2.addMouseListener(mouse);
            jp2.addMouseMotionListener(mouse);
            jb1.addActionListener(mouse);
            jb2.addActionListener(mouse);
            jb3.addActionListener(mouse);
            jb4.addActionListener(mouse);
            jbc1.addActionListener(mouse);
            jbc2.addActionListener(mouse);
        }
    }
    

    2、事件监听器部分:addMouseListener类,继承了多个动作监听器接口

    2.1 首先在actionPerformed获取目前状态:画什么,用什么颜色

    2.2 在按下去 mousePressed 、释放 mouseReleased 中分别获取当时坐标,用绘制函数绘制直线和矩形

    if(name.equals("线条")||name.equals("")){
        g.drawLine(x1,y1,x2,y2);
    }
    
    if(name.equals("矩形")){
        g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
    }

    2.3 在点击mouseClicked中,用函数绘制多边形

    第一次按压记录x0;第二次之后,绘制上一次点击位置和本次点击位置的直线;双击之后,绘制上一次点击位置和本次点击位置+x0与本次双击点的两条直线

    g.drawLine(x01,y01,x02,y02); //第二次以后
    g.drawLine(x0,y0,x01,y01);   //双击后
    

    2.4 在拖拽mouseDragged中,绘制两次时间段之间的直线,时间段片小,则显示出来像曲线

    g.drawLine(x,y,xt,yt);
    package Draw;
    
    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.awt.event.MouseMotionListener;
    
    //MouseListener:绘制直线、矩形、多边形
    //ActionListener:动作监听,获取button的text,来判断目前处于何种工作状态
    //MouseMotionListener:拖动画线
    public class addMouseListener implements MouseListener ,ActionListener , MouseMotionListener{
        //变量如下,分别对应直线、矩形x1,x2;多边形x01,x02,x0;
        private int x1=0,y1=0,x2=0,y2=0;
        private int x=0,y=0,xt=0,yt=0;
        private int x01,y01,x02,y02,x0,y0;
        private Graphics g ;
        private String name = "线条";
        private Color jbcolor = Color.BLACK;
    
        //构造方法,将画笔传入监听器,在监听器中动作执行时,绘制相应图形
        public addMouseListener(Graphics gr){
            this.g = gr;
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            //3-多边形绘制,最后双击,在第一个点和最后一个点的位置之间画线
            if(e.getClickCount()==2){
                System.out.println("双击!!");
                g.drawLine(x0,y0,x01,y01);
                x0=0;y0=0;x01=0;y01=0;x02=0;y02=0;
            }
            System.out.println("点击");
    
            if(name.equals("多边形")) {
                //当第一次按压,x01=0时候,则将第一次按压坐标存入x0,y0
                if(x01==0){
                    x0 = e.getX();
                    y0 = e.getY();
                }
                x01 = e.getX();
                y01 = e.getY();
                //第二次按压以后画线
                if (x02!=0){
                    g.drawLine(x01,y01,x02,y02);
    
                }
                //将本次x01按压存入x02,用于下一次绘制直线
                x02 = x01;
                y02 = y01;
            }
    
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
            //1线条-2矩形-按压时为绘制起点x1,y1
            System.out.println("按压");
            x1 = e.getX();
            y1 = e.getY();
    
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            //1线条-2矩形-释放时为绘制终点x2,y2
            System.out.println("释放");
            x=0;y=0;xt=0;yt=0;
            x2 = e.getX();
            y2 = e.getY();
            //
            if(name.equals("线条")||name.equals("")){
                g.drawLine(x1,y1,x2,y2);
            }
    
            if(name.equals("矩形")){
                g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
            }
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            System.out.println("进入");
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            System.out.println("离开");
        }
    
    
        @Override
        public void mouseDragged(MouseEvent e) {
            //拖动绘制
            if(name.equals("绘制")){
                x = e.getX();
                y = e.getY();
                if(xt!=0){
                    g.drawLine(x,y,xt,yt);
                }
                xt = x;
                yt = y;
            }
    
        }
    
        @Override
        public void mouseMoved(MouseEvent e) {
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
    
            if(e.getActionCommand().equals("蓝色")){
                //定义新的jb按钮对象,来接受e.getSource()的object对象,强制转型为JButton
                JButton jb = (JButton)e.getSource();
                jbcolor = jb.getForeground();
                g.setColor(jbcolor);
            }else if(e.getActionCommand().equals("绿色")){
                JButton jb = (JButton)e.getSource();
                jbcolor = jb.getForeground();
                g.setColor(jbcolor);
            }else{
                name = e.getActionCommand();
            }
    
            System.out.println("button:"+name);
    
        }
    }
    

       结果:如下   

    三、重绘    ❤️【本章节三个类组成最终代码】❤️

    1、需要重绘,则需要数组存储下绘制过的线条

    定义Shape类

    属性:包括初始坐标、终止坐标、绘制形状、颜色

    方法:重新画方法,调用该方法,将shape中的对象重新绘制出来

    package com.java7.DrawRedraw0710;
    
    import java.awt.*;
    
    public class Shape {
        private int x1,y1,x2,y2;
        private String name;
        private Color color;
    
        public Shape(int x1,int y1,int x2,int y2,String name,Color color){
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.name = name;
            this.color = color;
        }
        //重绘中,调用Redraw,则绘制shape对象
        public void Redraw(Graphics g){
            System.out.println("Graphics name = "+name);
            g.setColor(color);
            switch (name){
                case "线条":
                    g.drawLine(x1,y1,x2,y2);
                    break;
                case "矩形":
                    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
                    break;
            }
        }
    }
    

    2、定义好shape类后,我们需要在在监听器类,绘制的时候,将坐标、颜色、绘制种类存入Shape,再将Shape存入ShapeArray[]数组。

    //1.把线条坐标、名称存入Shape
    Shape shape = new Shape(x1,y1,x2,y2,name,jbcolor);
    shapeArray[index++] = shape;
    //3.1.单击后,把多边形的初始坐标、名称存入Shape
    Shape shape = new Shape(x01,y01,x02,y02,"线条",jbcolor);
    shapeArray[index++] = shape;
    //3.2.双击后,把多边形的初次按下坐标+最后按压的坐标、名称存入Shape;清空所有坐标,用于下一次判断是否为第一次按压
    Shape shape = new Shape(x0,y0,x01,y01,"线条",jbcolor);
    shapeArray[index++] = shape;
    x0=0;y0=0;x01=0;y01=0;x02=0;y02=0;
    

    源码:addMouseListener类

    package com.java7.DrawRedraw0710;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class addMouseListener implements MouseListener ,ActionListener , MouseMotionListener{
    
        private int x1=0,y1=0,x2=0,y2=0;
        private int x=0,y=0,xt=0,yt=0;
        private int x01,y01,x02,y02,x0,y0;
        private Graphics g ;
        private String name = "线条";
        private Color jbcolor=Color.BLACK;
    
        //重绘:
        private Shape shapeArray[];
        private int index = 0;
        //set函数,使用后,初始化画笔gr,shapeArray[]数组,用于将其传入addMouseListener
        public void setGr(Graphics gr){
            this.g = gr;
        }
        public void setSa(Shape shapeArray[]){
            this.shapeArray = shapeArray;
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            if(e.getClickCount()==2){
                g.drawLine(x0,y0,x01,y01);
                //3.2.双击后,把多边形的初次按下坐标+最后按压的坐标、名称存入Shape
                Shape shape = new Shape(x0,y0,x01,y01,"线条",jbcolor);
                shapeArray[index++] = shape;
                x0=0;y0=0;x01=0;y01=0;x02=0;y02=0;
            }
        }
    
        public void mousePressed(MouseEvent e) {
            //System.out.println("按压");
            x1 = e.getX();
            y1 = e.getY();
    
        }
    
        public void mouseReleased(MouseEvent e) {
            x=0;y=0;xt=0;yt=0;
            x2 = e.getX();
            y2 = e.getY();
            System.out.println("name="+name);
            if(name.equals("线条")||name.equals("")){
                g.drawLine(x1,y1,x2,y2);
                //1.把线条坐标、名称存入Shape
                Shape shape = new Shape(x1,y1,x2,y2,name,jbcolor);
                shapeArray[index++] = shape;
            }
    
            if(name.equals("矩形")){
                g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));
                //2.把矩形坐标、名称存入Shape
                Shape shape = new Shape(x1,y1,x2,y2,name,jbcolor);
                shapeArray[index++] = shape;
            }
    
            if(name.equals("多边形")) {
                System.out.println("多边形");
                if(x01==0){//第一次按下,记录地刺次按下的位置,用于双击后,多边形闭合
                    x0 = e.getX();
                    y0 = e.getY();
                }
                x01 = e.getX();
                y01 = e.getY();
    
                if (x02!=0){//第二次按压
                    g.drawLine(x01,y01,x02,y02);
                    //3.1.单击后,把多边形的初始坐标、名称存入Shape
                    Shape shape = new Shape(x01,y01,x02,y02,"线条",jbcolor);
                    shapeArray[index++] = shape;
                }
                x02 = x01;
                y02 = y01;
            }
        }
    
        public void mouseEntered(MouseEvent e) {
            ///System.out.println("进入");
        }
    
        public void mouseExited(MouseEvent e) {
            //System.out.println("离开");
        }
    
    
        public void mouseDragged(MouseEvent e) {
            if(name.equals("绘制")){
                System.out.println("DRAGE —— 拖动绘制曲线:");
                x = e.getX();
                y = e.getY();
                if(xt!=0){
                    g.drawLine(x,y,xt,yt);
                    //把坐标、名称存入Shape
                    Shape shape = new Shape(x,y,xt,yt,"线条",jbcolor);
                    shapeArray[index++] = shape;
                }
                xt = x;
                yt = y;
            }
        }
    
        public void mouseMoved(MouseEvent e) {
        }
    
        public void actionPerformed(ActionEvent e) {
            //首先获取jb对象(JButton)e.getSource();再对象的颜色jb.getBackground()
            if("".equals(e.getActionCommand())){
                JButton jb = (JButton)e.getSource();
                jbcolor = jb.getBackground();
                g.setColor(jbcolor);
            }
            //获取动作:直线、矩形、多边形、拖动绘制线条
            else{
                name = e.getActionCommand();
                System.out.println("button:"+name);
            }
        }
    }
    

    3、 主函数,继承JPanel,在重写panit()函数时,写入:绘制shapeArray[]数组中所有的Shape对象。

    @Override
    public void paint(Graphics g) {
        //调用重绘
        super.paint(g);
        for(int i=0;i<shapeArray.length;i++){
            if(shapeArray[i]!=null){
                shapeArray[i].Redraw(g);
            }
            else
                break;
        }
        System.out.println("重绘");
    }
    

    源码:SampleDraw

    package com.java7.DrawRedraw0710;
    
    import javax.swing.*;
    import java.awt.*;
    
    public class SampleDraw extends JPanel{
        public static void main(String args[]){
            SampleDraw draw = new SampleDraw();
            draw.showUI();
        }
        private Shape shapeArray[]=new Shape[1000];
    
        @Override
        public void paint(Graphics g) {
            //调用重绘
            super.paint(g);
            for(int i=0;i<shapeArray.length;i++){
                if(shapeArray[i]!=null){
                    shapeArray[i].Redraw(g);
                }
                else
                    break;
            }
            System.out.println("重绘");
        }
    
        public void showUI(){
            //界面
            JFrame jf = new JFrame();
            jf.setTitle("画图1.0");
            jf.setSize(800,800);
            jf.setLocationRelativeTo(null);
            jf.setDefaultCloseOperation(3);
    
            //JPanel
            JPanel jp1 = new JPanel();
            jp1.setBackground(Color.white);
            jf.add(jp1,BorderLayout.NORTH);
            jf.add(this,BorderLayout.CENTER);
    
            //按钮
            JButton jb1 = new JButton("线条");
            JButton jb2 = new JButton("矩形");
            JButton jb3 = new JButton("多边形");
            JButton jb4 = new JButton("绘制");
    
            jp1.add(jb1);
            jp1.add(jb2);
            jp1.add(jb3);
            jp1.add(jb4);
    
            //鼠标监听器,初始化设置shapeArray
            addMouseListener mouse = new addMouseListener();
    
            //颜色数组,循环添加颜色按钮
            Color colorArray[] = {Color.GREEN,Color.BLUE,Color.CYAN};
            for(int i=0;i<colorArray.length;i++){
                JButton jb = new JButton();
                jb.setBackground(colorArray[i]);
                jb.setForeground(colorArray[i]);
                jp1.add(jb);
                jb.addActionListener(mouse);
            }
    
            //可见放在add之后,获取之前
            jf.setVisible(true);
    
            //画布,添加至jpanel2
            Graphics gr = this.getGraphics();
            System.out.println("graphics = " + gr);
    
            //添加鼠标监听器
            this.addMouseListener(mouse);
            this.addMouseMotionListener(mouse);
    
            jb1.addActionListener(mouse);
            jb2.addActionListener(mouse);
            jb3.addActionListener(mouse);
            jb4.addActionListener(mouse);
    
            mouse.setGr(gr);//使得鼠标中的位置,获取画布类:鼠标在画布上画线、多边形
            mouse.setSa(shapeArray);//获得shapeArray,用于paint中重绘
    
        }
    
    }
    

    结果:

  • 相关阅读:
    Ubuntu-12.04.5 安装 oracle 12.2.0.1 数据库database软件
    Ubuntu-12.04.5 再再再次安装 oracle 11.2.0.4 数据库database软件(又不一样了!)
    Ubuntu-4.10 安装 oracle 11.2.0.4 数据库database软件(最古老的ubuntu)
    PATH add
    可望不可即 可望不可及
    天干地支
    24节气
    二进制、十进制和十六进制转换器
    信用卡三磁道
    ISO8583
  • 原文地址:https://www.cnblogs.com/iriswang/p/11084649.html
Copyright © 2011-2022 走看看