`
siyanglu
  • 浏览: 15184 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

再言画板的总结

 
阅读更多


      依旧是画板,已经写到第七个版本了,与上篇所说的相比,除了界面加上了一个可变画图面板,代码上进行了一些优化以外,还加上了画板的重绘,这样,就不用担心窗体最小化之后所画图形未保存了。下面上代码。

package Draw20111020;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 自制简单画图板,第七次修正 
 * @author 鲁大帅
 */
public class Draw05 extends JFrame {
	//参数
	private ImpList<NetJavaShape> shapes = new ImpList<NetJavaShape>();//定义一个队列用来存放数组对象
	private boolean isChange = false;//用于后面的判断
	private Graphics2D g;//画布定义成2D的,主要是因为加上了粗细这个参数
	
	/** 主函数 */
	public static void main(String[] args) {
		Draw05 htb = new Draw05();
		htb.showUI();
	}
	
	/** 实现界面的方法*/
	public void showUI() {
		this.setTitle("鲁大帅的画板");// 设置标题
		this.setSize(600, 430);// 设置窗体大小
		this.setDefaultCloseOperation(3);// 关闭的时候自动退出程序
		this.setLocationRelativeTo(null);// 窗体显示位置居中
		
		// 设置边框布局对象
		BorderLayout bl = new BorderLayout();
		this.setLayout(bl);

		/** 添加四个面板 */
		ToolBar tb = new ToolBar();// 工具栏
		MyMenuBar mb = new MyMenuBar();// 菜单栏
		ColorBox cp = new ColorBox();// 颜色栏
		final JPanel center = new JPanel();// 右边面板

		// //设置布局为流式,左对齐,上下,左右间距为5px,背景颜色为灰
		center.setLayout(new FlowLayout(0, 5, 5));
		center.setBackground(Color.GRAY);

		final JPanel dp = new JPanel(){
			public void paint(Graphics g){	
				super.paint(g);//调用父类的方法来绘制窗体
				drawshape((Graphics2D)g);//调用绘制形状的方法
			}
		};// 设置画图的面板
		
		dp.setBackground(Color.WHITE);// 颜色为白色
		dp.setPreferredSize(new Dimension(400, 260));
		center.add(dp);

		/** 添加面板到窗体 */
		this.add(tb, BorderLayout.WEST);
		this.add(mb, BorderLayout.NORTH);
		this.add(cp, BorderLayout.SOUTH);
		this.add(center, BorderLayout.CENTER);

		this.setVisible(true);// 窗体可见

		MyListener ml = new MyListener(dp, tb, cp,shapes);// 实现鼠标监听
		dp.addMouseListener(ml);
		dp.addMouseMotionListener(ml);

		// 拖动改变画布大小的实现
		// 在匿名内部类中使用外面的局部变量,一定要定义成final
		MouseAdapter ms = new MouseAdapter() {
			int cursors;
			//移动到右下角时改变光标的形状
			public void mouseMoved(MouseEvent e) {
				int x = e.getX();
				int y = e.getY();
				if (x > dp.getPreferredSize().getWidth()
						&& x < dp.getPreferredSize().getWidth() + 10
						&& y > dp.getPreferredSize().getHeight()
						&& y < dp.getPreferredSize().getHeight() + 10)   
					// 改变光标的形状
				{	center.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
				cursors = 1;
					isChange = true;
					//右边和下面中点的情况
				} else if (x > dp.getPreferredSize().getWidth()/2
							&& x < dp.getPreferredSize().getWidth()/2 + 10
							&& y > dp.getPreferredSize().getHeight()
							&& y < dp.getPreferredSize().getHeight() + 10){
					center.setCursor(new Cursor(Cursor.S_RESIZE_CURSOR));
					cursors = 2;
					isChange = true;
				}else if(x > dp.getPreferredSize().getWidth()
						&& x < dp.getPreferredSize().getWidth() + 10
						&& y > dp.getPreferredSize().getHeight()/2
						&& y < dp.getPreferredSize().getHeight()/2 + 10){
					center.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
					cursors = 3;
					isChange = true;
				}else {
					// 设置为默认光标
					center.setCursor(Cursor.getDefaultCursor());
					isChange = false;
				}
			}

			public void mouseReleased(MouseEvent e) {
				int x = e.getX();
				int y = e.getY();
				int x1 = (int) dp.getPreferredSize().getWidth();
				int y1 = (int) dp.getPreferredSize().getHeight();
				if (isChange) {
					if(cursors == 1){
					// 设置画布面板的大小
						dp.setPreferredSize(new Dimension(x - 5, y - 5));
					}else if(cursors == 2){
						dp.setPreferredSize(new Dimension(x1,y -5));
					}else if(cursors == 3){
						dp.setPreferredSize(new Dimension(x-5,y1));
					}
					// 刷新
					javax.swing.SwingUtilities.updateComponentTreeUI(dp);
					center.setCursor(Cursor.getDefaultCursor());
					isChange = false;
				}
			}
		};

		center.addMouseListener(ms);
		center.addMouseMotionListener(ms);
		dp.addMouseMotionListener(ms);
	}

	private void drawshape(Graphics2D g) {
		//遍历队列
		for(int i=0;i<shapes.size();i++){
			NetJavaShape ss = shapes.get(i);
			ss.draw(g); 	
		}
	}
}

  

      以上是主函数,有些地方还是看起来很累赘,但目前能做的只有这样了。画板实现了主界面添加菜单栏,工具栏,颜色栏,可改变画布大小以及画布重绘等功能。工具栏和颜色栏虽有有些稍微的区别,但大体构架还是一样的,下面只说颜色栏。代码如下:

package Draw20111020;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;

/**
 * 颜色栏外加颜色监听
 * @author Administrator
 *
 */

public class ColorBox extends javax.swing.JToolBar{
	
	//设置参数
	private int col;//用于后面左右键的判断
	private Color color;
	//点击左右键所得的颜色
	private Color lcolor=Color.BLACK;
	private Color rcolor=Color.WHITE;
	
	public ColorBox(){
		colorchoose();	
	}
	
	/**获得左右键颜色的值的方法*/
	public Color getlColor(){
		return lcolor;
	}	
	public Color getrColor(){
		return rcolor;
	}	
	/**选择颜色的方法*/
	public void colorchoose(){
		/**
		 * color面板设置大小、颜色、流式布局
		 */
		this.setName("颜色");
		this.setPreferredSize(new Dimension(600,90));//设置大小
		FlowLayout g0 = new FlowLayout(FlowLayout.LEFT);
			this.setLayout(g0);
		
		/**
		 * 创建一个工具条,2个面板,jp1放置颜色监听,jp2放置颜色面板
		 */
			JPanel jtb = new JPanel();
			JPanel jp1 = new JPanel();
			JPanel jp2 = new JPanel();
			
			jp1.setPreferredSize(new Dimension(41,41));//设置大小
				jp1.setLayout(null);
				jp1.setBackground(Color.WHITE);
			jp2.setPreferredSize(new Dimension(282,41));//设置大小
				
		/**对于jp1,设置front、back两面板,自由布局*/
			final JButton front = new JButton();
			final JButton back = new JButton();//新建两按钮
			front.setPreferredSize(new Dimension(15,15));//面板大小
			back.setPreferredSize(new Dimension(15,15));
			
			front.setBounds(10,10,15,15);
			back.setBounds(16,16,15,15);//设置location
			
			front.setBackground(Color.BLACK);
			back.setBackground(Color.WHITE);//设置初始背景色
			
			back.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					showColorSelecter();
				}
			});//匿名内部类给back添加动作监听,点击调出颜色选择器
			
			jp1.add(front);
			jp1.add(back);//添加两面板
			
		/**添加鼠标监听器*/
			MouseAdapter al=new MouseAdapter(){
				
				// 点击时返回对象数值
				public void mouseClicked(MouseEvent e) {
					
					//获得点击的值以判断左右键
					col = e.getButton();
					//获得对象
					Object obj = e.getSource();
					//强制转型
						JButton but = (JButton)obj;
					//获得color的值
					color = but.getBackground();
					//判断,如果点击左键,则设置front颜色;如果是右键,则设置back颜色
					if(col==1){
						front.setBackground(color);	
						lcolor=color;
						}
					else if(col==3){
						back.setBackground(color);
						rcolor=color;
					}
				}
				 
			};
					
		/**对于jp2,用于装颜色面板*/
			
			//定义一个Color数组
			Color colorbox[]={Color.BLACK,new Color(128,128,128),new Color(128,0,0),new Color(128,128,0),new Color(0,128,0),new Color(0,128,128),new Color(0,0,128),
					new Color(128,0,128),new Color(128,128,64),new Color(0,64,64),new Color(0,128,255),new Color(0,64,128),new Color(128,0,255),new Color(128,64,0),
							  Color.WHITE,new Color(192,192,192),new Color(255,0,0),new Color(255,255,0),new Color(0,255,0),new Color(0,255,255),new Color(0,0,255),
		  new Color(255,0,255),new Color(255,255,128),new Color(0,255,128),new Color(128,255,255),new Color(128,128,255),new Color(255,0,128),new Color(255,128,64)};
			
			//通过for循环添加数组中按钮
			
			for(int i=0;i<28;i++){
				JButton btn = new JButton();
					btn.setBackground(colorbox[i]);
					btn.setPreferredSize(new Dimension(15,15));
					btn.addMouseListener(al);
				jp2.add(btn);
			}
			
			//将面板加到工具条上
			jtb.add(jp1);
			jtb.add(jp2);
			
			 // 将工具条加到大面板上 
			this.add(jtb);
	}
		/**调出颜色选择器的方法*/
		private void showColorSelecter(){
			this.color = javax.swing.JColorChooser.showDialog(null, "请选择颜色", java.awt.Color.BLACK);
		
	}
	
}

         完成了各个面板,接下来就是将他们连接起来的监听器了,来看看这个:

public class MyListener extends MouseAdapter{
	/**
	 * 定义参数
	 */
	private int x1,y1,x2,y2;
	private Color color;
	private Graphics2D g;
	private String command="pencil";
	private ToolBar tb;
	private ColorBox cp;
	private int col;
	private JPanel dp;
	//定义一个队列用来保存绘制的形状
	private ImpList<NetJavaShape> shapes ;
	
	public MyListener(JPanel dp,ToolBar tb,ColorBox cp,ImpList<NetJavaShape> shapes){
		this.dp = dp;
		this.tb = tb;
		this.cp = cp;
		this.shapes = shapes;
	}
	//鼠标按下事件,取得起始坐标
	public void mousePressed(MouseEvent e) {

		g = (Graphics2D)dp.getGraphics();
		
		//col作为判断左右键颜色的依据,获得color值
		col=e.getButton();
		if(col==1){
		color = cp.getlColor();
		}else if(col==3){
			color=cp.getrColor();
		}
		 x1 = e.getX();
		 y1 = e.getY();
	 }
	
	 //鼠标拖拽事件,画曲线
	  public void mouseDragged(MouseEvent e){
			x2=e.getX();
			y2=e.getY();
			
		 command = tb.getCommand();      //从tb中获得command的值
		 NetJavaShape s1= null;
		 
	 /**曲线的画法*/ 
		if(command.equals("pencil")){
		 s1= new Impline(x1,y1,x2,y2,1,color);  
		 s1.draw(g);
			x1=x2;
			y1=y2;    
		}else if(command.equals("eraser")){
	 /**橡皮*/	
		 s1= new Imperaser(x1,y1,x2,y2,10,Color.WHITE);
		 s1.draw(g);
			x1=x2;
			y1=y2;    
		}
		 shapes.add(s1);
	  }
	    //鼠标按下得到终点坐标
	 public void mouseReleased(MouseEvent e) {
		 x2 = e.getX();
		 y2 = e.getY();
		 NetJavaShape s2=new Impline(x1,y1,x2,y2,1,color);
		if(command.equals("line")){
			s2 = new Impline(x1, y1, x2, y2,1,color);    //直线
		 }else if(command.equals("rect")){
			 s2 = new Imprect(x1, y1, x2, y2,1,color);     //矩形
		 }else if(command.equals("oval")){
			 s2 = new Impoval(x1, y1, x2, y2,1,color);     //椭圆
		 }else if(command.equals("rounded_rect")){
			 s2= new ImpRoundRect(x1, y1, x2, y2,1,color);     //圆角矩形
		 }else if(command.equals("polygon")){
			 s2 = new Impjt(x1, y1, x2, y2,1,color);     //三角形
		 }
		 s2.draw(g);
		 dp.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		 shapes.add(s2);	 
	 }
}

       监听器从主函数得到了画布对象和队列,又从颜色面板得到了画笔的颜色,这样一来,就可以通过监听和判断绘制图形了。本人不才,仅仅只实现了画曲线、直线、矩形、椭圆、圆角矩形、一个坑爹的三角形和橡皮。对与这些图形的画法,首先定义了一个抽象类NetJavaShape,所有的形状画法皆继承于此,绘制的方法大同小异。下面以矩形为例。下面有三种画法:第一种为最复杂,也最易理解,即分四种情况讨论x1、x2,y1、y2的大小。

if(x1<x2&&y1<y2){g.drawRect(x1, y1, x2-x1, y2-y1); }
else if(x1<x2&&y1>y2){g.drawRect(x1, y2, x2-x1, y1-y2);} 
else if(x1>x2&&y1<y2){g.drawRect(x2, y1, x1-x2, y2-y1);} 
else if(x1>x2&&y1>y2){g.drawRect(x2, y2, x1-x2, y1-y2);} 

   

      第二种是我自己的囧方法,即把边界通过画直线四点连接起来,这里就不说了。第三种是来自龙哥的很巧妙方法,看似简单,对我这种初学者来说确实很难想到。

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

      一个小小的矩形就有这样不同的的写法,这说明要实现目标,方法是很多的。套用一句话:“没有做不到,只有想不到。”的确如此。只要多思考,然后付诸实践,很多问题都能解决的。好的想法应该是成功的第一步吧。当然,要成功中间还有很长的路要走,但只要坚持下去,别放弃,一定能行的。即使失败了,也绝不后悔。

     至于队列的实现,这里就不写了。最后,再贴张图吧。

 

  • 大小: 64.9 KB
分享到:
评论

相关推荐

    玲珑画板 6.045 版安装.rar

    总结来说,玲珑画板6.045版是一款轻量级但功能强大的数学作图工具,它的出现为数学教育领域提供了新的可能性。无论是教学还是自学者,都可以从中受益,通过直观的图形化方式加深对数学的理解,提升学习效率。所以,...

    电子画板个人制作

    总结一下,电子画板是一个个人开发的创意工具,它利用鼠标输入模拟绘画和书写,特别适用于教育领域。通过回放功能,可以生动展示创作过程,增强教学效果。虽然可能不是市场上最强大的绘图软件,但其简易性和针对性使...

    几何画板在小学数学教学中的应用PPT课件.pptx

    总结起来,《几何画板》作为一款专业的数学教学工具,以其独特的特点和广泛的应用实例,有力地支持了小学数学的教学工作,提升了教学效果,同时也为学生的数学学习提供了更为丰富和立体的体验。教师们应该充分利用这...

    几何画板5.0打包机,网上不太好找了。

    总结而言,几何画板5.0打包机是一个不可或缺的工具,它弥补了几何画板5.0在文件分享上的不足,使得优秀的作品能跨越时间和空间的限制,继续在教育和研究领域发挥其价值。对于那些还在寻找这款打包机的用户,应当珍视...

    几何画板课件350套 (2).zip

    总结起来,"几何画板课件350套 (2).zip" 是一个全面的几何学教育资源,包含了大量的教学实例和练习,适用于教师的教学辅助和学生的学习巩固。无论是在课堂教学还是自主学习中,这个压缩包都能提供丰富的素材,帮助...

    易语言画板画显示器花屏损坏假象源码

    总结来说,“易语言画板画显示器花屏损坏假象源码”是一个易语言编程的学习资源,它利用易语言的画板组件和编程技巧,模拟出一种视觉效果,展示了易语言在图形编程方面的潜力。对于学习者而言,研究这个源码可以帮助...

    物理绘图 金排物理画板 v2019

    总结来说,金排物理画板v2019是一款集物理符号绘制、图形编辑、课件制作于一体的优秀软件,它极大地提升了物理工作者的工作效率,丰富了物理教学手段。对于那些需要精准表达物理概念的人来说,它无疑是一个不可或缺...

    易语言画板做的动态图画.rar

    《易语言画板动态图画详解》 易语言是一款由中国程序员王江民开发的,专为初学者设计的编程语言,其特色在于采用直观的...对于初学者而言,这是一个难得的实践机会,能够将理论知识转化为实际操作,提升编程技能。

    GDI内存画板_1.5-易语言

    总结而言,易语言内存画板模块是利用GDI技术在内存中进行高效、无闪烁绘图的工具,对于提升图形界面的用户体验具有显著作用。它简化了开发者处理复杂绘图任务的过程,为易语言的图形应用开发开辟了新的可能。通过...

    PCB封装库---经过很多次画板检验

    总结起来,"PCB封装库---经过很多次画板检验"是一个包含多种常用接口、芯片和元器件封装的资源集合,适用于不同类型的PCB设计。这个库的使用能够确保设计的规范性,提高设计质量和可靠性。对于电子工程师而言,拥有...

    易语言画板进度条源码-易语言

    总结来说,这个易语言画板进度条源码是一个很好的学习资源,它涵盖了控件操作、事件处理和图形绘制等多个知识点。对于想要在易语言环境下实现进度条功能的初学者而言,这是一个非常实用的起点。通过分析和运行这个...

    宣传部个人工作总结-4页.pdf

    对于个人而言,作者也认识到在人际交往中需要学会控制情绪,变得更加成熟和隐忍。 在团队氛围方面,作者表达了对部长和同事们的赞赏,他们的支持和陪伴让工作环境变得愉快。作者期望在未来的工作中,团队能更加团结...

    花瓣:中国版Pinterest.docx

    总结来说,花瓣网作为一个中国的社交图片分享平台,它将信息以视觉化的方式呈现,通过采集、画板和喜欢等功能,构建了一个让用户表达自我、发现新知、分享兴趣和互动交流的空间。与Pinterest一样,花瓣网证明了图片...

    GspForExe打包器(基于Gsp5.06制作)

    总结起来,"GspForExe打包器(基于Gsp5.06制作)"是一个实用的工具,它通过将GSP文件转换为EXE格式,极大地扩展了几何画板的应用场景,使得高质量的动态几何教学资源能够更广泛地传播和使用。对于教育工作者而言,它...

    C++ 写的画图工具

    在众多的应用中,利用C++编写画图工具是一种常见且有趣的实践,尤其对于学习计算机图形学的学生而言,这既是一个挑战,也是一个巩固理论知识和提升编程技能的好机会。本文将深入探讨如何使用C++来构建一个简单的画图...

    Sketchpad5.zip

    总结来说,Sketchpad5作为一款几何画板,不仅提供了一个直观的几何图形创建平台,还涵盖了函数、测量、计算等多个数学领域,实现了动态几何教学的创新。它通过互动和可视化的方式,帮助教师更有效地传授知识,让学生...

    绘图GDI+技巧及相关的应用

    对于开发人员而言,理解和掌握这些技术至关重要,不仅能够提升程序的用户体验,还能优化资源利用效率。 #### 二、关键技术点解析 ##### 1. 如何防止记录不必要的绘图过程中的痕迹? 在绘制过程中,有时会遇到需要...

    行业分类-设备装置-便携式镶嵌支架纸本写生箱.zip

    此外,支架部分采用了可调节角度的设计,可以根据光线条件和个人习惯自由调整,确保画板始终保持理想的工作角度。 其次,该设备的“镶嵌”特性十分独特。镶嵌技术使得支架与写生箱合二为一,写生箱内可以安全地存放...

    小学一年级家长会家长代表发言稿.doc

    ”一年级的孩子就像是空白的画板,他们的行为和性格很大程度上取决于我们的引导。因此,我们对汪天意从小进行规范化的教育,比如要求他在学习前后洗手,整理好自己的书桌,保持作业本和书籍的整洁,以及在读书时做到...

    基于同一美术爱好的小学生美术学习共同体模式构建.docx

    1. 准备阶段:教师提前安排好出行时间,确保天气适宜,准备好所需的画具和材料,如画板、颜料、铅笔、橡皮等,并向学生讲解安全注意事项。 2. 实地观察:到达目的地后,让学生们自由分散,仔细观察荷花的形态和周围...

Global site tag (gtag.js) - Google Analytics