张小艾 发表于 2021-12-14 22:19:55

JAVA swing 简易画板

GitHub上抄了个简易画板的代码
源自:(https://github.com/Fattybenny/javaswingproject/tree/main/%E6%A8%A1%E6%8B%9F%E7%94%BB%E5%9B%BE%E5%B7%A5%E5%85%B7)
一个简易的画板,copy到eclipse 后报错情况在图片里
就是提示Paint类里jb.addActionListener(lis);jb.addActionListener(lis);这两行报错
大佬们帮忙看看啥问题,(当然能给个差不多的画板源代码也可以)谢谢{:10_266:}

源码如下:

package swing_01;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import java.awt.event.ActionEvent;


public class Listener extends MouseAdapter{
        //一定要将接口的所有方法重写
        private int index=0;
        private Graphics gr;
        private String command="";       
        private Paint p;
        private Color color=Color.black;
        int x0=0,y0=0,//曲线的起始坐标
          x1=0,y1=0,x2=0,y2=0,//其他图形
          x3=0,x4=0,y3=0,y4=0,
          start_x=0,start_y=0;//多边形起点

        //初始化数据
        //基本数据类型向形参传递的是副本,引用数据类型(类,接口,数组)向形参传递的地址,如下传递jp       
        public void set_gr(Graphics G) {
                this.gr = G;
        }       

        public void set_p(Paint p)
        {
                this.p=p;
        }
                       
        /*
       * getSource得到的组件的名称,而getActionCommand得到的是标签。
         如:Button bt=new Button("buttons");
             用getSource得到的是bt 而用getActionCommand得到的是:buttons
       */
        /*
       * 这里必须先点击被命名的按钮(即要画什么图形),将"zhiling"初始化,
       * 否则后面的监听回应方法都不能执行,如果不点击颜色按钮(只设置了按钮的背景颜色,没有settext),
       * 则不会为画笔setcolor
       * 默认黑色
       */
        public void actionPerformed(ActionEvent e)
        {
               
                // TODO Auto-generated method stub
                //在画板上描绘图案的时候用的是同一个画笔,只不过每次使用之前都把画笔的颜色修改了               
                               if (e.getActionCommand()=="") {
                          //j暂存颜色按钮
                        JButton j = (JButton)e.getSource();
                        //将画笔设置为按钮的背景颜色
                        color=j.getBackground();
                }
                else {
                        command = e.getActionCommand();
                        if("清除".equals(command))
                        {
                                Graphics cleang=p.getGraphics();
                                //JFrame和JPanel的repaint方法是同一个,都是继承自JComponent的,对该方法的调用执行的都是同样的代码的。
                               
                                        p.paint1(cleang);
                                p.shape=new Shape;
                                index=0;
                        }
                }
        }
       
        //鼠标按键在组件上按下(长按)并拖动时(在拖动的过程中)调用。   (处理鼠标拖动事件)
                        public void mouseDragged(MouseEvent e) {
                                //System.out.println("Drag");                               
                                if("曲线".equals(command)) {
                                        x1 = x0; y1 = y0; //鼠标按下的时候就获得了起始坐标
                                        x0 = e.getX(); y0 = e.getY();
                                        gr.drawLine(x1,y1,x0,y0);
                                        p.shape= new Shape(x1,y1,x0,y0,command,gr.getColor());
                                }
                        }
                
             
                        // Override鼠标监听//点击鼠标点击时间,用来绘画多边形
                        public void mouseClicked(MouseEvent e) //是点击和松开两步完成后才被再调用(前提是点击和松开的位置是相同点) 在此之前,pressed 和released都已经被调用
                                                                 
                        {      
                                System.out.println("鼠标click事件发生");
                                // TODO Auto-generated method stub
                                if("多边形".equals(command))
                                {
                                       
                                        if(x4==0&&y4==0)
                                          {
                                               
                                                x4 = e.getX(); y4 = e.getY();
                                                start_x = x4; start_y = y4;
                                                //记录多边形的起点位置
                                              }
                                       
                                        else {
                                                //System.out.println("Here is duobianxing ");
                                                x3 = x4; y3 = y4;//这里的x3,y3为上一条边的终点
                                                x4 = e.getX(); y4 = e.getY();
                                                gr.drawLine(x3, y3, x4, y4);//将这点与上一条边的终点连起来
                                                p.shape= new Shape(x3,y3,x4,y4,command,gr.getColor());
                                             }
                                        if(e.getClickCount()==2)
                                        {
                                        //System.out.println("双击");
                                        x4 =0; y4=0;//这里设置为零是为了能都再次执行if语句
                                        gr.drawLine(start_x, start_y, e.getX(), e.getY());//将双击的终点位置和开始记录的起点位置相连
                                        p.shape= new Shape(start_x, start_y, e.getX(), e.getY(),command,gr.getColor());
                                        }       
                                }
                        }
                               
                               //当鼠标按下的时候,获取起点的坐标
                               public void mousePressed(MouseEvent e)
                                {
                                          gr=p.getGraphics();
                                          gr.setColor(color);
                             System.out.println("pressed事件发生");
                                       
                                        if("曲线".equals(command)){
                                                x0 = e.getX();
                                                y0 = e.getY();
                                        }
                                        // TODO Auto-generated method stub
                                        x1 = e.getX();
                                        y1 = e.getY();
                                       
                                }
                               
                               
                                //当鼠标松开的时候,获取终点的坐标
                                public void mouseReleased(MouseEvent e)
                                {
                                        System.out.println("released事件发生");
                                        // TODO Auto-generated method stub
                                        x2 = e.getX();
                                        y2 = e.getY();
                               
                                        if("直线".equals(command)){
                                                gr.drawLine(x1, y1, x2, y2);
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                               
                                        }
                                        else if("矩形".equals(command)) {
                                                gr.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                        }
                                        else if("圆形".equals(command)) {
                                                //Math.min(x1, x2), Math.min(y1, y2),
                                                //drawoval 和drawrect 都是以某个点 向着坐标点增大的方向画图
                                                //Math.abs(x1-x2)求绝对值
                                                gr.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                                                                        }
                                }
                                //鼠标进入窗口
                                public void mouseEntered(MouseEvent e)
                                {
                                       
                                }
               //鼠标退出窗口
                          public void mouseExited(MouseEvent e)
                          {
                                 
                          }
                                //鼠标在移动的过程中调用(没有点击)
                          public void mouseMoved(MouseEvent e)
                         {
                               
                         }
                        
                               
                        }



package swing_01;
import java.awt.*;

import javax.swing.*;
public class Paint extends JPanel{

        //建立一个很大的数组,用来存放图形元素,
        Shape[] shape=new Shape;
        public static void main(String[] args) {
               new Paint();
        }
          JFrame jf = new JFrame();          
          
        //实例化一个ButtonListener对象,实现了多种接口
        Listener lis= new Listener();
       
        public Paint() {
                  //实现一个窗体
                  jf.setTitle("画图板");
                  jf.setLocation(600,250);//窗口左上角起点
                  jf.setSize(700, 600);
                  jf.setLayout(new FlowLayout());       
                  
                   //1.setPreferredSize需要在使用布局管理器的时候使用,布局管理器会获取空间的preferredsize,因而可以生效。
                  //例如borderlayout在north中放入一个panel,panel的高度可以通过这样实现:panel.setPreferredSize(new Dimension(0, 100));
                  //这样就设置了一个高度为100的panel,宽度随窗口变化。
                  //2.setSize,setLocation,setBounds方法需要在不使用布局管理器的时候使用,也就是setLayout(null)的时候可以使用这三个方法控制布局。
                  //区分好这两个不同点之后,

                  
          //声明两个数组,包含各种指令
                      String[] command = { "开始", "清除", "直线", "曲线", "多边形", "矩形","圆形" };
                      Color[] color = { Color.BLACK, Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN };
   
   
                    /*在下面的两个循环中将各种按钮添加进入动作监听器中,其中addActionListener参数为btl,
                  btl是一个Buttonlistener的对象
                  */
                     
                   for (int i = 0; i < command.length; i++) {
                           JButton jb = new JButton(command);
                           jb.addActionListener(lis);
                           jf.add(jb);
                   }
                   for (int i = color.length - 1; i >= 0; i--) {
                           JButton jb = new JButton();
                           jb.setBackground(color);//设置背景颜色
                           Dimension dm = new Dimension(20, 20);//设置大小
                           jb.setPreferredSize(dm);
                           jb.addActionListener(lis);
                           jf.add(jb);
                   }
                  
             //将JPanel对象添加进入jf窗体对象中,让他生效
          //jpanel画板的大小和颜色
                  this.setPreferredSize(new Dimension(1600, 1400));
          this.setBackground(Color.LIGHT_GRAY);
         
         
          //这里注意流程我们实在rootpane上进行流式布局 现将各个按钮添加完,在添加这个画板 P
                        jf.add(this);
                        jf.setDefaultCloseOperation(3);
                        jf.setVisible(true);        //设置可见
                           //Graphics gf = this.getGraphics();        //获取画笔,我们的this代表当前类的对象,正好是一个JPanel的对象
                           this.addMouseListener(lis);                //添加鼠标监听器,用于画图
                           this.addMouseMotionListener(lis);        //添加鼠标模式监听器,用于绘画曲线                        
                           lis.set_p(this);//给监听类当中的Paint 对象赋初值,方便通过p调用paint1 方法
        }
       
        //这里是重写jpanel中的paint   
        //????这里的重绘画笔与上面的gf应该不相同
       
        //一下知识点经验:当我们重写父类中的方法后,如果想在其他类中通过对象调用父类的方法时
        //应该再重新创建一个方法,名字与被重写的父类方法不同,这个方法不是重写,只是通过这个方法调用父类的方法
       
        public void paint(Graphics g)//前面有三角图案 代表是重写 (重写在当前的子类中)
        {
                super.paint(g);//这是原先的父类方法 本来只要绘制组件的功能
                     //所以现在我们要加一个绘制图形的功能如下
                for(int i=0;i<=shape.length;i++)
                {
                        if(shape!=null)
                        {
                             g.setColor(shape.getcolor());
                                shape.Repaint(g);
                        }
                        else
                                break;
                }
                System.out.println("paint");
        }
       
        public void paint1(Graphics g)
        {
                super.paint(g);
        }
       
}



package swing_01;

import java.awt.Color;
import java.awt.Graphics;

public class Shape{
private int x1,y1,x2,y2;
private String name;
private Graphics g;
private Color color;

public Shape(int x1,int y1,int x2,int y2,String name,Color color)
{
        this.x1=x1;
        this.x2=x2;
        this.y1=y1;
        this.y2=y2;
        this.name=name;
        this.color=color;
}

public Color getcolor()
{
        return color;
}

public void Repaint(Graphics g)
{
        switch(name)
        {
        case "直线":
                g.drawLine(x1, y1, x2, y2);
                break;
        case "矩形":
                g.drawRect(Math.min(x1, x2), Math.min(y1 ,y2), Math.abs(x1-x2), Math.abs(y1-y2));
                break;
        case "圆形":
                g.drawOval(Math.min(x1, x2), Math.min(y1 ,y2), Math.abs(x1-x2), Math.abs(y1-y2));
                break;
        case "曲线":
                g.drawLine(x1, y1, x2, y2);
                break;
        case "多边形":
                g.drawLine(x1, y1, x2, y2);
                break;
        }
}
}
       

412046761 发表于 2021-12-14 22:19:56

应该是引用问题给你修改下 你看看可以使不package iih.ci.test.swing;

import java.awt.Color;
import java.awt.Graphics;
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;

import javax.swing.JButton;


public class Listener implements ActionListener,MouseListener,MouseMotionListener {
        //一定要将接口的所有方法重写
        private int index=0;
        private Graphics gr;
        private String command="";       
        private Paint p;
        private Color color=Color.black;
        int x0=0,y0=0,//曲线的起始坐标
          x1=0,y1=0,x2=0,y2=0,//其他图形
          x3=0,x4=0,y3=0,y4=0,
          start_x=0,start_y=0;//多边形起点

        //初始化数据
        //基本数据类型向形参传递的是副本,引用数据类型(类,接口,数组)向形参传递的地址,如下传递jp       
        public void set_gr(Graphics G) {
                this.gr = G;
        }       

        public void set_p(Paint p)
        {
                this.p=p;
        }
                       
        /*
       * getSource得到的组件的名称,而getActionCommand得到的是标签。
         如:Button bt=new Button("buttons");
             用getSource得到的是bt 而用getActionCommand得到的是:buttons
       */
        /*
       * 这里必须先点击被命名的按钮(即要画什么图形),将"zhiling"初始化,
       * 否则后面的监听回应方法都不能执行,如果不点击颜色按钮(只设置了按钮的背景颜色,没有settext),
       * 则不会为画笔setcolor
       * 默认黑色
       */
        public void actionPerformed(ActionEvent e)
        {
               
                // TODO Auto-generated method stub
                //在画板上描绘图案的时候用的是同一个画笔,只不过每次使用之前都把画笔的颜色修改了               
                               if (e.getActionCommand()=="") {
                          //j暂存颜色按钮
                        JButton j = (JButton)e.getSource();
                        //将画笔设置为按钮的背景颜色
                        color=j.getBackground();
                }
                else {
                        command = e.getActionCommand();
                        if("清除".equals(command))
                        {
                                Graphics cleang=p.getGraphics();
                                //JFrame和JPanel的repaint方法是同一个,都是继承自JComponent的,对该方法的调用执行的都是同样的代码的。
                               
                                        p.paint1(cleang);
                                p.shape=new Shape;
                                index=0;
                        }
                }
        }
       
        //鼠标按键在组件上按下(长按)并拖动时(在拖动的过程中)调用。   (处理鼠标拖动事件)
                        public void mouseDragged(MouseEvent e) {
                                //System.out.println("Drag");                               
                                if("曲线".equals(command)) {
                                        x1 = x0; y1 = y0; //鼠标按下的时候就获得了起始坐标
                                        x0 = e.getX(); y0 = e.getY();
                                        gr.drawLine(x1,y1,x0,y0);
                                        p.shape= new Shape(x1,y1,x0,y0,command,gr.getColor());
                                }
                        }
                
             
                        // Override鼠标监听//点击鼠标点击时间,用来绘画多边形
                        public void mouseClicked(MouseEvent e) //是点击和松开两步完成后才被再调用(前提是点击和松开的位置是相同点) 在此之前,pressed 和released都已经被调用
                                                                 
                        {      
                                System.out.println("鼠标click事件发生");
                                // TODO Auto-generated method stub
                                if("多边形".equals(command))
                                {
                                       
                                        if(x4==0&&y4==0)
                                          {
                                               
                                                x4 = e.getX(); y4 = e.getY();
                                                start_x = x4; start_y = y4;
                                                //记录多边形的起点位置
                                              }
                                       
                                        else {
                                                //System.out.println("Here is duobianxing ");
                                                x3 = x4; y3 = y4;//这里的x3,y3为上一条边的终点
                                                x4 = e.getX(); y4 = e.getY();
                                                gr.drawLine(x3, y3, x4, y4);//将这点与上一条边的终点连起来
                                                p.shape= new Shape(x3,y3,x4,y4,command,gr.getColor());
                                             }
                                        if(e.getClickCount()==2)
                                        {
                                        //System.out.println("双击");
                                        x4 =0; y4=0;//这里设置为零是为了能都再次执行if语句
                                        gr.drawLine(start_x, start_y, e.getX(), e.getY());//将双击的终点位置和开始记录的起点位置相连
                                        p.shape= new Shape(start_x, start_y, e.getX(), e.getY(),command,gr.getColor());
                                        }       
                                }
                        }
                               
                               //当鼠标按下的时候,获取起点的坐标
                               public void mousePressed(MouseEvent e)
                                {
                                          gr=p.getGraphics();
                                          gr.setColor(color);
                             System.out.println("pressed事件发生");
                                       
                                        if("曲线".equals(command)){
                                                x0 = e.getX();
                                                y0 = e.getY();
                                        }
                                        // TODO Auto-generated method stub
                                        x1 = e.getX();
                                        y1 = e.getY();
                                       
                                }
                               
                               
                                //当鼠标松开的时候,获取终点的坐标
                                public void mouseReleased(MouseEvent e)
                                {
                                        System.out.println("released事件发生");
                                        // TODO Auto-generated method stub
                                        x2 = e.getX();
                                        y2 = e.getY();
                               
                                        if("直线".equals(command)){
                                                gr.drawLine(x1, y1, x2, y2);
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                               
                                        }
                                        else if("矩形".equals(command)) {
                                                gr.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                        }
                                        else if("圆形".equals(command)) {
                                                //Math.min(x1, x2), Math.min(y1, y2),
                                                //drawoval 和drawrect 都是以某个点 向着坐标点增大的方向画图
                                                //Math.abs(x1-x2)求绝对值
                                                gr.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
                                                p.shape= new Shape(x1,y1,x2,y2,command,gr.getColor());
                                                                                        }
                                }
                                //鼠标进入窗口
                                public void mouseEntered(MouseEvent e)
                                {
                                       
                                }
               //鼠标退出窗口
                          public void mouseExited(MouseEvent e)
                          {
                                 
                          }
                                //鼠标在移动的过程中调用(没有点击)
                          public void mouseMoved(MouseEvent e)
                         {
                               
                         }
                        
                               
                        }

张小艾 发表于 2021-12-15 19:29:40

412046761 发表于 2021-12-14 22:19
应该是引用问题给你修改下 你看看可以使不

已经可以,谢谢大佬{:10_254:}
页: [1]
查看完整版本: JAVA swing 简易画板