`

重绘的实现

 
阅读更多
在以前制作的简单画板中,每当变动窗体时画出的图形都会消失,这个问题就需要通过重绘来实现。
重绘的原理:屏幕上的所有东西事实上都是由一个个的点绘制而成,包括窗体本身。JFrame类中有一个方法paint(),每当打开窗体时系统都会自动调用这个方法,把窗体画出来。

那么要想在窗体变动时窗体上画出的图案和窗体一样仍然存在,可以在定义时重写paint()的方法,在其中写上画这些图形的方法。这样,就需要从事件处理类中获得一些坐标,由于坐标的数量不定,而且画的基本图形不定,可以用队列存储这些信息。队列中的每个元素是一个数组,用数组中的第一个元素存储画的基本图形。

  1、在事件处理类中,定义一个队列作为属性,存储坐标
  2、在写绘制方法时,每次画基本图形时都新建一个数组存储坐标,把数组加入队列,同时用数组中指定的元素表示基本图形的种类(比如下面的例子中我用每个数组的第一个元素表示图形的种类)
  3、在paint()方法中调用事件处理类中队列的数据,根据表示图形种类的元素的值绘制图形

如下是重绘谢尔宾斯基地毯的部分代码:

1、在事件处理类中,定义一个队列作为属性,存储坐标

static SingleLinkList<int[]> mylinklist = new SingleLinkList<int[]>();


2、在写绘制方法时,每次画基本图形时都新建一个数组存储坐标,把数组加入队列,同时用数组中指定的元素表示基本图形的种类
 
/**
	 * 用square1绘制最大的正方形(边框为黑色)
	 * @param x1 
	 * @param x2
	 * @param a
	 * @param count
	 */
	public void square1(int x1,int x2,int a,int count){
        //绘制最大的正方形
		g.setColor(Color.BLACK);
		g.drawRect(x1, x2, a, a);
		int[] shape1=new int[5];
		 shape1[0]=21;shape1[1]=x1;shape1[2]=x2;shape1[3]=a;shape1[4]=a;
		 mylinklist.add(shape1);
		g.drawRect(x1-1, x2-1, a+2, a+2);
		int[] shape2=new int[5];
		shape2[0]=21;shape2[1]=x1-1;shape2[2]=x2-1;shape2[3]=a+2;shape2[4]=a+2;
		 mylinklist.add(shape2);
		g.drawRect(x1-2, x2-2, a+4, a+4); 
		int[] shape3=new int[5];
		shape3[0]=21;shape3[1]=x1-2;shape3[2]=x2-2;shape3[3]=a+4;shape3[4]=a+4;
		 mylinklist.add(shape3);
		
		//调用square2绘制内部正方形
		square2(a,x1,x2,count);
	}
	//用square2绘制内部的正方形(边框为白色)
	public void square2(int a,int x1,int x2,int count){
		//绘制中间第一个小正方形,用s表示小正方形边长
		int s=a/3;
		g.setColor(Color.BLACK);
		g.fillRect(x1+s, x2+s, s, s);
		int[] shape=new int[5];
		shape[0]=31;shape[1]=x1+s;shape[2]=x2+s;shape[3]=s;shape[4]=s;
		 mylinklist.add(shape);
		
		g.setColor(Color.WHITE);
		//设置第一行小正方形的左上角坐标
		int f1=x1;
		int f2=x2;
		int g1=x1+s;
		int g2=x2;
		int h1=x1+2*s;
		int h2=x2;
		//设置第二行小正方形的左上角坐标
		int i1=x1;
		int i2=x2+s;
		int k1=x1+2*s;
		int k2=x2+s;
		//设置第三行小正方形的左上角坐标
		int l1=x1;
		int l2=x2+s*2;
		int m1=x1+s;
		int m2=x2+s*2;
		int n1=x1+s*2;
		int n2=x2+s*2;
		//画出周围八个正方形
		g.drawRect(f1,f2,s,s);
		int[] shape8=new int[5];
		shape8[0]=20;shape8[1]=f1;shape8[2]=f2;shape8[3]=s;shape8[4]=s;
		 mylinklist.add(shape8);
		
		g.drawRect(g1,g2,s,s);
		int[] shape1=new int[5];
		shape1[0]=20;shape1[1]=g1;shape1[2]=g2;shape1[3]=s;shape1[4]=s;
		 mylinklist.add(shape1);
		
		g.drawRect(h1,h2,s,s);
		int[] shape2=new int[5];
		shape2[0]=20;shape2[1]=h1;shape2[2]=h2;shape2[3]=s;shape2[4]=s;
		 mylinklist.add(shape2);
		
		g.drawRect(i1,i2,s,s);
		int[] shape3=new int[5];
		shape3[0]=20;shape3[1]=i1;shape3[2]=i2;shape3[3]=s;shape3[4]=s;
		 mylinklist.add(shape3);
		
		g.drawRect(k1,k2,s,s);
		int[] shape4=new int[5];
		shape4[0]=20;shape4[1]=k1;shape4[2]=k2;shape4[3]=s;shape4[4]=s;
		 mylinklist.add(shape4);
		
		g.drawRect(l1,l2,s,s);
		int[] shape5=new int[5];
		shape5[0]=20;shape5[1]=l1;shape5[2]=l2;shape5[3]=s;shape5[4]=s;
		 mylinklist.add(shape5);
		
		g.drawRect(m1,m2,s,s);
		int[] shape6=new int[5];
		shape6[0]=20;shape6[1]=m1;shape6[2]=m2;shape6[3]=s;shape6[4]=s;
		 mylinklist.add(shape6);
		
		g.drawRect(n1,n2,s,s);
		int[] shape7=new int[5];
		shape7[0]=20;shape7[1]=n1;shape7[2]=n2;shape7[3]=s;shape7[4]=s;
		 mylinklist.add(shape7);
		
		
		count--;
		if(count<0) return;
		//通过递归绘制谢尔宾斯基地毯
		square2(s,f1,f2,count);
		square2(s,g1,g2,count);
		square2(s,h1,h2,count);
		square2(s,i1,i2,count);
		square2(s,k1,k2,count);
		square2(s,l1,l2,count);
		square2(s,m1,m2,count);
		square2(s,n1,n2,count);
	}


3、在paint()方法中调用事件处理类中队列的数据,根据表示图形种类的元素的值绘制图形

/**
	 * 重写JFrame中的paint方法
	 */
	public void paint(Graphics g){
		super.paint(g);
		 for(int i=1;i<=Listener.mylinklist.size();i++){
	        	ListNode<int[]> array=Listener.mylinklist.getNode(i);
	        	int[] a=array.getData();
	        	if(a[0]==21){
	        		g.setColor(Color.BLACK);
	        		g.drawRect(a[1]+200,a[2],a[3],a[4]);
	        	}else if(a[0]==31){
	        		g.setColor(Color.BLACK);
	        		g.fillRect(a[1]+200,a[2],a[3],a[4]);
	        	}else if(a[0]==20){
	        		g.setColor(Color.WHITE);
	        		g.drawRect(a[1]+200,a[2],a[3],a[4]);
	        	}
	        }
	}
	
分享到:
评论

相关推荐

    Qt使用QWidget重绘实现圆环形渐变色进度条(支持不确定进度模式)

    Qt中使用QWidget重绘实现圆环形渐变色进度条,支持不确定进度模式,支持设置背景图片,另外组件的整体尺寸,圆环粗细,各部分颜色,字体都是可以随意调整的,还支持QWidget的QSS语句调整背景色,外边框等,灵活度很...

    Mfc实现Edit重绘

    本文将深入探讨如何在MFC中实现Edit控件的重绘,包括编辑框的边框处理、文字居中、非客户区与客户区的绘制,以及针对VS2010中黑影问题的解决方案。 1. **Edit控件的边框重绘** 在MFC中,我们可以利用消息映射机制...

    MFC 基本常用控件重绘

    在这个项目中,开发者可能已经实现了上述控件的自定义重绘,并提供了示例以展示如何在实际应用中应用这些技术。 总之,MFC中的控件重绘是一项增强应用程序界面个性化和用户体验的重要技术。通过理解并实践ListCtrl...

    MFC普通窗口重绘

    本文将深入探讨MFC中的“普通窗口重绘”这一关键知识点,包括重绘的原因、过程以及如何在MFC应用中实现窗口重绘。 首先,窗口重绘是一个常见的需求,它通常发生在以下几种情况:窗口被其他窗口覆盖后暴露出来,窗口...

    C# winforms ComboBox 重绘

    在.NET Framework中,控件的重绘主要通过Override控件的`OnPaint`方法实现。当你需要自定义ComboBox的显示样式时,可以创建一个继承自ComboBox的新类,然后覆盖`OnPaint`方法,编写自己的绘制逻辑。 2. **自定义...

    C#重绘windows窗体标题栏和边框

    C#重绘Windows窗体标题栏和...C#重绘Windows窗体标题栏和边框是指使用C#语言来自定义Windows窗体的标题栏和边框的样式,通过使用WndProc方法来截获Windows消息,并实现自定义的绘制过程,从而实现更加个性化的界面。

    c#Winform Combox控件重绘

    重绘可以通过覆盖控件的`OnPaint`事件来实现,这是一个关键的自定义绘图方法。在Combox控件的重绘过程中,我们将自定义绘制其背景、边框、文本等元素,以达到个性化的视觉效果。 步骤1:创建项目 打开Visual Studio...

    窗体控件重绘

    重绘Form可以实现透明、半透明效果,或者自定义标题栏和边框样式。通过处理`Paint`事件,可以使用`ControlPaint`类的方法或者直接绘制图形。 3. **CheckBox控件重绘**:CheckBox的重绘可能包括改变选中状态的表示...

    Duilib 控件重绘教程附带例子

    本教程将重点讲解如何在Duilib中进行控件的重绘,以实现自定义的视觉效果。 控件重绘是Duilib中实现界面个性化的重要手段。通过重绘,我们可以改变控件的默认外观,比如修改边框样式、调整颜色、添加图案或者动画...

    MFC控件重绘MFC控件重绘

    在Windows系统中,每个控件都有一个默认的绘制方式,但有时为了实现特定的视觉效果或者界面风格,开发者需要自定义控件的绘制行为,这就是控件重绘。MFC提供了两种主要的机制来实现这一点:`OnDraw`方法和消息映射。...

    控件重绘 C# 轻松实现对窗体(Form)换肤

    最后,`SkinFormDemo`很可能是示例项目的名称,它可能包含了一个实现上述功能的完整示例,包括皮肤配置文件、皮肤管理器类、窗体和控件的重绘逻辑等。通过学习和分析这个示例,开发者可以更直观地理解和掌握C#中控件...

    MFC ComboxBox重绘类

    在这个场景中,我们关注的是`CMyComboBox`,这是一个自定义的组合框(ComboBox)类,它是MFC中的标准`CComboBox`类的扩展,专门为了实现自定义重绘功能而设计。 在MFC中,`CComboBox`类是用来处理Windows API中的...

    C# TreeView重绘边框

    本文将深入探讨如何在C#中实现`TreeView`控件的边框重绘,以创建独一无二的视觉效果。 首先,了解`TreeView`的基本属性和方法。`TreeView`控件具有`Nodes`集合,用于添加、删除或操作节点;`DrawMode`属性可以设置...

    自绘/重绘MFC右键菜单CMenu

    本篇文章将详细讲解如何在MFC应用中实现自绘或重绘右键菜单CMenu,以创建更具个性化的用户界面。 自绘(Custom Draw)或重绘(Redraw)是指在系统默认渲染的基础上,程序员通过调用特定的API函数或MFC类的方法来...

    MFC CListCtrl重绘,功能全

    在某些情况下,为了实现更复杂或个性化的界面效果,我们可能需要对CListCtrl进行重绘。本篇将深入探讨CListCtrl的重绘机制和如何实现全面的功能。 首先,理解CListCtrl的绘制过程至关重要。CListCtrl默认使用...

    winform gdi+重绘窗体 控件

    本文将深入探讨如何使用C#和GDI+来实现Winform窗体及控件的重绘功能,包括button、listbox、checkbox等常见控件,以及换肤的概念。 1. **Winform窗体的重绘** - Winform窗体的重绘通常涉及到`OnPaint`事件。当窗体...

    重绘 C# button按钮

    本节将详细介绍如何通过重绘技术实现自定义的C#按钮。 首先,理解WinForms中的控件绘制原理至关重要。Windows Forms控件,包括Button,都是基于GDI+图形接口进行绘制的。默认情况下,系统会自动处理控件的绘制,但...

    form重绘的方法

    在C#编程中,Form重绘是一个常见的任务,主要用于自定义控件的外观或实现动态效果。当需要改变窗体的视觉样式,如颜色、形状等时,重绘功能就显得尤为重要。本教程将深入探讨如何在C#中实现Form的重绘,以及解决过程...

    重绘ComBoBox 实现修改TextColor

    重绘ComBoBox 实现修改TextColor 控件的DrawMode要修改为OwnerDrawFixed或者OwnerDrawVariable

    ComboBox重绘

    前段时间做登录框,想把ComboBox做的和qq的那个一样,结果发现微软默认的控件不能实现,经过两天的研究并结合网上资料,于是用edit、btn以及list 三个控件组合重绘实现ComboBox功能,希望对大家有所帮助。

Global site tag (gtag.js) - Google Analytics