java---画板

本文详细介绍了如何使用Java构建一个功能丰富的画板应用,包括界面生成、工具栏组件、监听器添加以及画图机制。通过重写MouseListener和MouseMotionListener,实现了画直线、矩形、椭圆等图形功能,还涵盖了铅笔、橡皮、喷漆等工具的实现。此外,还讨论了如何通过监听器设置颜色,使画板更加生动多彩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 仿XP画图板

这个画板现在可以实现的功能包括话各种图形、铅笔、喷漆、刷子、橡皮、吸管取色这些。下面就来一步步分析下这个画板是怎么实现的吧! 

一、界面的生成

      大体分析一下一个画图板界面可以分成那些部分:整体的一个大窗体,处于最顶部的一个菜单栏,左侧的工具栏,中间空白的画图纸,下部的颜色选择器以及底部有一条帮助提示栏。最早我所做的画图板把这些生成界面的相关代码都给写在了同一个类里面,其中包括各种组件的添加和布局,那样写的话就会显得十分的乱,想要修改某一部分就要在里面找上好久。后来这个最新弄得画板在生成这个界面的时候采用的方法是每一部分的组件单独成一类,在每一个类中写一个初始化的方法,并且重载他的构造方法,这样只要在主类中调用他的构造方法再合理的安排一下布局就可以了。这样做每一部分组件单独成类显得十分清晰,但也有一定的不足,就是在这些类与后来定义的监听器类之间相互传递参数的时候就会很麻烦,经常传参数传的自己头昏脑胀的。。但肯定没有万全的方法吧,看自己习惯怎么弄了~~

各个组件部分是怎么生成的在这里我就不一一列出来了,这儿就把左侧工具栏部分的生成用代码表示一下,其它部分都相似的。

 

Java代码 package db.xyz.DrawBoardTool; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import db.xyz.Listener.DrawListener; import db.xyz.Listener.HelpListener; public class DrawBoardTool extends JPanel{ DrawListener dListener; public DrawBoardTool(DrawListener dListener){ this.dListener = dListener; unitTools(); } public void unitTools(){ //设置工具栏布局为流式布局 this.setLayout(new FlowLayout()); //创建一个窗体对象 JPanel panel = new JPanel(); //设置布局为网格布局 panel.setLayout(new FlowLayout()); panel.setPreferredSize(new Dimension(70,300)); //数组存放图片位置 String [] tool = {"image/line.png","image/pencil.png","image/rect.png","image/frect.png","image/oval.png","image/foval.png","image/zhex.png","image/erase.png","image/penqi.png","image/brush.png","image/roundrect.png","image/xiqu.jpg"}; //数组存放控制命令 String [] command = {"line","pencil","rect","frect","oval","foval","zhex","erase","penqi","brush","roundrect","xiqu"}; HelpListener dl = new HelpListener(); for(int i = 0;i" wmode="transparent"> 收藏代码
  1. "font-size: medium;">package db.xyz.DrawBoardTool;  
  2.   
  3. import java.awt.BorderLayout;  
  4. import java.awt.Color;  
  5. import java.awt.Dimension;  
  6. import java.awt.FlowLayout;  
  7. import javax.swing.ImageIcon;  
  8. import javax.swing.JButton;  
  9. import javax.swing.JPanel;  
  10.   
  11. import db.xyz.Listener.DrawListener;  
  12. import db.xyz.Listener.HelpListener;  
  13.   
  14.   
  15.   
  16. public class DrawBoardTool extends JPanel{  
  17.     DrawListener dListener;  
  18.       
  19.     public DrawBoardTool(DrawListener dListener){  
  20.         this.dListener dListener;  
  21.         unitTools();      
  22.      
  23.       
  24.     public void unitTools(){  
  25.         //设置工具栏布局为流式布局  
  26.         this.setLayout(new FlowLayout());  
  27.         //创建一个窗体对象  
  28.         JPanel panel new JPanel();  
  29.         //设置布局为网格布局  
  30.         panel.setLayout(new FlowLayout());  
  31.         panel.setPreferredSize(new Dimension(70,300));  
  32.         //数组存放图片位置  
  33.         String [] tool {"image/line.png","image/pencil.png","image/rect.png","image/frect.png","image/oval.png","image/foval.png","image/zhex.png","image/erase.png","image/penqi.png","image/brush.png","image/roundrect.png","image/xiqu.jpg"};  
  34.         //数组存放控制命令  
  35.         String [] command {"line","pencil","rect","frect","oval","foval","zhex","erase","penqi","brush","roundrect","xiqu"};  
  36.         HelpListener dl new HelpListener();  
  37.         for(int 0;i
  38.             ImageIcon imgIcon new ImageIcon(tool[i]);  
  39.             //创建JButton按钮对象添加图标设置大小  
  40.             JButton button new JButton(imgIcon);  
  41.             button.setPreferredSize(new Dimension(30,30));  
  42.             //将按钮添加到panel上  
  43.             panel.add(button);  
  44.             button.setActionCommand(command[i]);  
  45.             button.addActionListener(dListener);  
  46.             button.addMouseListener(dl);  
  47.                     
  48.         JPanel panel_sel new JPanel();  
  49.         panel_sel.setBackground(Color.LIGHT_GRAY);  
  50.         panel_sel.setPreferredSize(new Dimension(60,80));  
  51.         panel.add(panel_sel);         
  52.         this.add(panel);  
  53.      
  54.  
  55.   

 可以看一下这里添加各个组件的按钮时候采用的是一个循环,这样添加图标可以节省很多语句,并且在每个循环添加按钮的同时也对这些按钮添加了按钮图片图标,设置了动作命令。生成这样一个产生工具栏的类后,在主类中只要实例化一个DrawBoardTool类的对象,再设置他的布局为放置在西边的边框布局就完成了工具栏的添加。

 其他那些组建模块的生成与添加的代码就不再这里列出了,因为都是很相似的,最后会付全部代码的。

 

二、监听器的添加——使画板有生命

 这样在添加了各个组件之后的画板只可以说是形似XP的画图板,但他却是一个死的。~无法执行任何动作,除非右上角的关闭按钮。接下来就是要让这个画板富有生命,我们点击直线,就可以在白纸上画直线……

之前关于监听器只接触过动作监听器就是ActioinListener。但这里在画图的时候需要的就是与鼠标有关监听器:MouseListener和MouseMotionListener。这两个监听器都有着自己的方法,其中MouseListener有五个方法,分别对应的操作是鼠标按下、松开、进入、移出和点击。MouseMotionListener只有一个鼠标拖动的方法。这些方法足以完成我们的画图板。

关于监听器具体怎么用就不用我说明了吧。看这些文章的都是大牛们。~我也只总结一下在设置这些监听器时容易出错的地方吧。

先来了解下画图的机制吧,就比如画直线,我们鼠标按下进行拖动,然后松开的时候屏幕上就会出现一条直线。怎么画直线的方法不需要我们自己去写,Graphics类中已经定义好了方法:drawLine(x1,y1,x2,y2);可以看出这个方法是需要传入4个参数的,分别是两个点的4个坐标,这样调用这个方法后就会在这两个点之间生成一条直线。所以分析一下我们只需要得到的就是鼠标按下开始拖动时的那个起始点的坐标以及最后松开画直线时的那个终点的坐标,就可以完成这个直线。

我们就要重写MouseListener这个接口中的方法:mousePressed和mouseReleased。

Java代码 public void mousePressed(MouseEvent e) { String command = e.getActionCommand(); x1 = e.getX(); y1 = e.getY(); } public void mouseReleased(MouseEvent e) { int x2 = e.getX(); int y2 = e.getY(); if(command.equals("line")){ //画一条直线 db.g.drawLine(x1,y1,x2,y2); }" wmode="transparent"> 收藏代码
  1. "font-size: medium;">public void mousePressed(MouseEvent e)  
  2.     String command e.getActionCommand();  
  3.                 x1 e.getX();  
  4.         y1 e.getY();  
  5.          
  6.   
  7. public void mouseReleased(MouseEvent e)  
  8.                 int x2 e.getX();  
  9.         int y2 e.getY();  
  10.         if(command.equals("line")){  
  11.             //画一条直线           
  12.             db.g.drawLine(x1,y1,x2,y2);      
  13.         }  

 这样就可以画直线了!其中有一句代码String command = e.getActionCommand();他的作用是获取动作命令。我们在添加按钮的时候给每一个按钮都赋予了不同的动作命令,这样是为了判断我们选择的究竟是那一个按钮要执行那一种操作。在监听器里面调用 e.getActionCommand();就可以获得所按按钮的动作命令,这里获取动作命令之后判断如果是"line"那么就是要画直线,所以在鼠标松开的时候调用了drawLine那个方法来画直线。
这里还要说一下那个g是什么东西~~g说白了就是画布,就是那片白纸。我们在生成画布之后要调用一个方法:Graphics g = dpaper.getGraphics(); 这个语句的作用就是获取画布,就是为了知道我们要在哪里进行作图的。

 

现在这个画图板已经可以画一条直线了,与画直线类似的还有(内填充)矩形,(内填充)椭圆,圆角矩形这些,说相似但也不完全相同,有一点还是需要注意的。以画矩形为例,我们查看API中drawRect这个方法发现他也有四个参数:int x, int y, int width, int height。很显然这四个参数是一个点的一对儿坐标和长还有宽。这里如果还是像之前画直线那样把x1赋给x,y1赋给y。x2-x1赋给width,y2-y1赋给height。如果这样的话,运气好的话我们是可以话出来一个矩形的,但只能正确的画出一种矩形,就是鼠标拖动的方向是从左上向右下的。其他的矩形会偏离我们鼠标所滑动的区域。那这是为什么呢?其实只要我们好好看一下drawRect这个方法,好好看下他的四个参数代表的东西就会发现问题:坐标xy是矩形的左上点的坐标。所以我们鼠标按下松开获取的x1x2y1y2这四个坐标,我们就要从中找出左上角的那个坐标。不难分析,窗体左上角的坐标为(0,0)。所以左上角的坐标是较小的,所以只需调用一个取较小值的一个方法Math.min(x1,x2),Math.min(y1, y2)这样分别赋给x,y就可以了。另外,长宽的设置,我们也不能直接就x2-x1,y2-y1,需要对其取一个绝对值,这一点很好理解吧。那就是Math.abs(x1-x2),Math.abs(y1-y2)。这样就可以正确的画出一个矩形了。

 

现在那些直线、矩形、椭圆这些都可以实现了。下面再总结下铅笔那一类工具的实现。

如果我们打开windows自带的画板,使用铅笔工具画一段曲线,再用放大镜来观看,就会发现:铅笔所画出的曲线其实就是一段段很短的直线连接所形成!这就给我们写铅笔的方法带来了灵感。但这里还需要用到另一个监听器:MouseMotionListener。它里面只有一个方法:MouseDragged。很显然这个方法是在鼠标拖动的时候调用。所以我们在鼠标按下的时候获取到x1,y1这初始坐标,之后每拖动一次就获取一对(x3,y3)坐标,并在这两个点之间画一段小直线,之后再把这个(x3,y3)赋给(x1,y1)作为下一段直线的初始坐标,当拖动后再来画出下一小段直线,如此往复就可以完成铅笔的功能啦!

Java代码 public void mouseDragged(MouseEvent e) { //画铅笔 if(command.equals("pencil")){ x3 = e.getX(); y3 = e.getY(); db.g.drawLine(x1,y1,x3,y3); x1 = x3; y1 = y3; }" wmode="transparent"> 收藏代码
  1. "font-size: medium;">public void mouseDragged(MouseEvent e)  
  2.         //画铅笔  
  3.         if(command.equals("pencil")){  
  4.         x3 e.getX();  
  5.         y3 e.getY();  
  6.         db.g.drawLine(x1,y1,x3,y3);  
  7.         x1 x3;  
  8.         y1 y3;  
  9.         }  

 铅笔弄好啦那什么橡皮和刷子自然而成。喷漆的做法也如此,只不过喷漆还要多一个随机数,就是在周围多少坐标的范围内随机生成一定的小点点来实现喷漆的功能:

Java代码 //画喷漆 else if(command.equals("penqi")){ x3 = e.getX(); y3 = e.getY(); Random rand = new Random(); //使用循环,来画15个小点 for(int i=0;i<15;i++){ //在20个像素点的范围内随机一个值 int tempx = rand.nextInt(20); int tempy = rand.nextInt(20); //开始画点了 db.g.drawLine(x3+tempx, y3+tempy, x3+tempx, y3+tempy); } }" wmode="transparent"> 收藏代码
  1. "font-size: medium;">//画喷漆        
  2. else if(command.equals("penqi")){  
  3.     x3 e.getX();  
  4.     y3 e.getY();  
  5.     Random rand new Random();  
  6.     //使用循环,来画15个小点  
  7.     for(int i=0;i<</SPAN>15;i++){  
  8.         //在20个像素点的范围内随机一个值  
  9.         int tempx rand.nextInt(20);  
  10.         int tempy rand.nextInt(20);  
  11.         //开始画点了  
  12.         db.g.drawLine(x3+tempx, y3+tempy, x3+tempx, y3+tempy);  
  13.      
  14.           
  15. }  

这样画图板的这些基本功能就都完成了。还有一个就是吸管取色的功能,这个再下一篇关于画图板的重绘操作时再来介绍吧!

 

三、让画图板靓丽起来

现在虽然各个组件的功能都已实现,但却都是黑色的,画的只有黑色的直线,黑色的矩形、椭圆……那么就要使我们可以给作图设置颜色。这个就很简单了。我们之前在界面中已经把颜色条儿给生成了,那么我们只要使一个监听器坚挺那些按钮,再通过动作命令来判断所选择的颜色,在调用setColor这个方法就可以完成了!

 

到现在,这个画板的基本功能就完成啦~~快来画出自己喜欢的图案吧!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值