advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement


ParticleText


Java Source:


import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.util.StringTokenizer;
import java.applet.*;

public class ParticleText extends Applet implements Runnable{

	// Initial Configuration:
	private static int imgW = 640;
	private static int imgH = 120;
	private static int targetFPS = 40;
	private static int morphDelay = 1500;

	private static int fontSize = 36;
	private static boolean useBlur = true;
	private static boolean useSineShift = true;

	private float periodFactor = 0.02f;
	private float scaleFactor = 15;

	private static Color backColor = Color.black;
	private static Color fontColor = new Color(255,245,170);
	private static float waveShiftSpeed = 0.1f;
	private static String fontName = "Arial";


	// The text to be displayed:
	String[] credSplit={new String(""),
						new String("Three Rings -"),
						new String("for the Elven-kings -"),
						new String("under the sky,"),
					 	new String("Seven for the Dwarf-lords -"),
					 	new String("in their halls of stone,"),
					 	new String("Nine for Mortal Men -"),
					 	new String("doomed to die,"),
					 	new String("One for the Dark Lord -"),
					 	new String("on his dark throne"),
					 	new String("In the Land of Mordor -"),
					 	new String("where the Shadows lie."),
					 	new String(""),
					 	new String("One Ring to rule them all,"),
					 	new String("One Ring to find them,"),
					 	new String("One Ring to bring them all"),
					 	new String("and in the Darkness -"),
					 	new String("bind them"),
					 	new String("In the Land of Mordor"),
					 	new String("where the Shadows lie."),
					 	new String(""),
					 	new String("Ash nazg durbatulūk,"),
					 	new String("ash nazg gimbatul,"),
					 	new String("ash nazg thrakatulūk"),
					 	new String("agh burzum-ishi krimpatul."),
					 	new String(""),
					 	new String(""),
					 	new String("Quote from"),
					 	new String("The Lord Of The Rings"),
					 	new String("by J.R.R Tolkien"),
					 	new String("as you should know :)"),
					 	new String(""),
					 	new String("If you've watched"),
					 	new String("this long,"),
					 	new String("you should probably"),
					 	new String("find something -"),
					 	new String("better to do ^_^"),
					 	new String("..."),
					 	new String(""),
					 	new String("-- T H E  E N D --"),
					 	new String(""),
					 	new String(""),
					 	new String("")
	};


	// -- Variables -- //

	// Thread:
	private Thread myThread;	// The main thread..

	// Pixel arrays:
	private int[] pixCur;	// Current pixels

	// Points:
	private int[] posX;			// X position
	private int[] posY;			// Y position
	private int[] destX;		// Destination X
	private int[] destY;		// Destination Y
	private int[] pointCol;		// Point color
	private byte[] finPoint;	// Which points are finished?

	// Other:
	private MemoryImageSource memSrc;
	private Image bb;
	private Image imgText;
	private ColorModel colModel;
	private Graphics g;

	private Font myFont;
	private FontRenderContext frc;
	private Rectangle2D txtBounds;
	private PixelGrabber pg;

	private int[] imgPix;
	private int[] myShift = new int[imgW];
	private byte setPoints[] = new byte[imgW*imgH];

	private boolean destroy = false;
	private boolean stop = false;
	private float waveShift=0;



	public void init(){
		System.out.println("Init method called");
	}

	public void start(){
		System.out.println("Start method called");

		getParams();
		initPix();
		initPoints(2000,fontColor.getRGB());

		//imgText = new BufferedImage(imgW,imgH,BufferedImage.TYPE_INT_RGB);
		imgText = createImage(imgW,imgH);
		colModel = new DirectColorModel(32,0x00ff0000,0x0000ff00,0x000000ff);
		memSrc = new MemoryImageSource(imgW,imgH,colModel,pixCur,0,imgW);
		memSrc.setAnimated(true);
		bb = createImage(memSrc);

		// Fix font settings in Text Image:
		g = imgText.getGraphics();
		myFont = new Font(fontName,Font.BOLD,fontSize);
		g.setFont(myFont);
		frc = ((Graphics2D)g).getFontRenderContext();
		((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		((Graphics2D)g).setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_ON);

		// Initialize with first string:
		newCred(credSplit[0]);

		// Start running:
		this.stop = false;
		myThread = new Thread(this);
		myThread.start();

	}

	public void stop(){
		// Flag running loop to stop:
		this.stop = true;
		this.destroy = false;
		destroy();
	}

	public void destroy(){
		this.stop = true;
		this.destroy = true;
	}

	private void newCred(String newCredStr){
		int curPointCount = posX.length;
		int newPointCount=0;
		int curPoint=0;
		int rndPoint=0;
		int initCol=backColor.getRGB()&(0x00FFFFFF);
		int index=0, maxPix=0;
		int pX=0,pY=0;

		int[] newPosX;
		int[] newPosY;
		int[] newDestX;
		int[] newDestY;
		int[] newPointCol;
		byte[] newFinPoint;

		// Draw text:
		g.setColor(backColor);
		g.fillRect(0,0,imgW,imgH);

		txtBounds = myFont.getStringBounds(newCredStr,frc);
		g.setColor(fontColor);
		g.setFont(myFont);
		g.drawString(newCredStr,(int)((imgW-txtBounds.getWidth())/2),(int)((imgH-txtBounds.getHeight())/2)+fontSize);
		pg = new PixelGrabber(imgText,0,0,imgW,imgH,imgPix,0,imgW);

		// Grab pixels:
		try {
	    	pg.grabPixels();
		} catch (InterruptedException e) {
	    	System.err.println("interrupted waiting for pixels!");
	    	return;
		}

		// Find the points:
		maxPix = imgPix.length;
		index = 0;
		while(index<maxPix){
			if((imgPix[index]&(0x00FFFFFF))!=initCol){
					// Found a point.
					curPoint++;
				}
			index++;
		}
		newPointCount = curPoint;

		if(newPointCount==0){
			initPoints(2000,fontColor.getRGB());
			return;
		}

		// Create new arrays:
		newPosX = new int[newPointCount];
		newPosY = new int[newPointCount];
		newDestX = new int[newPointCount];
		newDestY = new int[newPointCount];
		newPointCol = new int[newPointCount];
		newFinPoint = new byte[newPointCount];

		// Initialize new points:
		index=0; curPoint=0;
		pX=0; pY=0;
		while(index<maxPix){
			if((imgPix[index]&(0x00FFFFFF))!=initCol){
				// Found a point.
				newDestX[curPoint] = pX;
				newDestY[curPoint] = pY;
				newPointCol[curPoint] = imgPix[index];
				newFinPoint[curPoint] = 0;

				if(curPoint<curPointCount){
					newPosX[curPoint] = posX[curPoint];
					newPosY[curPoint] = posY[curPoint];
				}else{
					rndPoint = (int)(Math.random()*curPointCount);
					newPosX[curPoint] = posX[rndPoint];
					newPosY[curPoint] = posY[rndPoint];
				}
				curPoint++;
			}
			index++;
			pX++;
			if(pX==imgW){
				pX=0;
				pY++;
			}
		}

		// Set new points:
		posX = newPosX;
		posY = newPosY;
		destX = newDestX;
		destY = newDestY;
		pointCol = newPointCol;
		finPoint = newFinPoint;

		// Swap destinations some times:
		swapDests(newPointCount>>1);

	}

	private void initPix(){

		// Create pixel array:
		pixCur = new int[imgW*imgH];
		imgPix = new int[imgW*imgH];

		// Init pixels:
		for(int j=0;j<imgH;j++){
			for(int i=0;i<imgW;i++){
				pixCur[(j*imgW)+i] = 0;
			}
		}
	}

	private void initPoints(int pointCount, int color){
		posX = new int[pointCount];
		posY = new int[pointCount];
		destX = new int[pointCount];
		destY = new int[pointCount];
		pointCol = new int[pointCount];
		finPoint = new byte[pointCount];

		int rndX=0;
		int rndY=0;

		for(int i=0;i<pointCount;i++){
			rndX = (int)(Math.random()*imgW);
			rndY = (int)(Math.random()*imgH);

			posX[i] = rndX;
			posY[i] = rndY;

			rndX = (int)(Math.random()*imgW);
			rndY = (int)(Math.random()*imgH);

			destX[i] = rndX;
			destY[i] = rndY;

			pointCol[i] = color;

		}
	}

	private void swapDests(int timesToSwap){
		int tmp=0;
		int index1=0;
		int index2=0;
		int pointCount = posX.length-1;

		// Swap the point destinations some times:
		for(int i=0;i<timesToSwap;i++){
			index1 = (int)(Math.random()*pointCount);
			index2 = (int)(Math.random()*pointCount);

			tmp = destX[index1];
			destX[index1] = destX[index2];
			destX[index2] = tmp;

			tmp = destY[index1];
			destY[index1] = destY[index2];
			destY[index2] = tmp;

			tmp = pointCol[index1];
			pointCol[index1] = pointCol[index2];
			pointCol[index2] = tmp;

		}
	}

	private boolean movePoints(){

		int finishedCount=0;
		int pointCount = posX.length;

		int velX=0;
		int velY=0;

		byte finX=0;
		byte finY=0;

		// Loop through all points:
		for(int i=0;i<pointCount;i++){
			// Check whether the point has reached its destination:
			if(!(finPoint[i]==1)){

				// Update velocity:
				velX = (destX[i]-posX[i])>>4;
				velY = (destY[i]-posY[i])>>4;

				// Check whether the point should reach the destination now:
				finX = 0;
				finY = 0;

				if(velX==0){
					velX = (destX[i]-posX[i]);
					finX = 1;
				}
				if(velY==0){
					velY = (destY[i]-posY[i]);
					finY = 1;
				}

				// Update position:
				posX[i]+=velX;
				posY[i]+=velY;

				if(finX==1 && finY==1){
					finPoint[i]=1;
					finishedCount++;
				}
			}else{
				// Point finished.
				finishedCount++;
			}
		}

		if(finishedCount==pointCount){
			// Morph finished.
			return true;
		}else{
			return false;
		}
	}

	public void drawPoints(){
		int pointCount = posX.length;
		int initCol = backColor.getRGB();
		int r=0,g=0,b=0;
		int rgb=0;
		int pX=0;
		int pY=0;
		int index = 0;
		int pixMax = 0;
		int initR=0,initG=0,initB=0;
		int i1=0,i2=0,i3=0,i4=0;

		initR = (initCol & 0x000000FF);
		initG = (initCol & 0x0000FF00)>>8;
		initB = (initCol & 0x00FF0000)>>16;


		// Fade old points:
		// ---------------------------------------------------------------------------
		pixMax = pixCur.length;
		pX = 0;
		pY = 0;
		if(useBlur){
			while(index<pixMax){

				// Get pixel color:
				rgb = pixCur[index];

				// Get color components:
				r = (rgb    )&0xFF;
				g = (rgb>>8 )&0xFF;
				b = (rgb>>16)&0xFF;

				// Multiply by 8, subtract 1x and add init Color:
				r=((r<<3)-r)+initR;
				g=((g<<3)-g)+initG;
				b=((b<<3)-b)+initB;

				// Divide result by 8:
				r>>=3;
				g>>=3;
				b>>=3;

				// Set new pixel:
				pixCur[index] = (r)|(g<<8)|(b<<16);
				setPoints[index] = 0;	// Re-initialize the rendered points array at the same time..

				// Update position:
				index++;
				pX++;
				if(pX==imgW){
					pX=0;
					pY++;
				}
			}
		}else{
			while(index<pixMax){
				pixCur[index] = initCol;
				setPoints[index] = 0;
				index++;
			}
		}
		// ---------------------------------------------------------------------------


		// Compute new shift values:
		if(useSineShift){
			for(int i=0;i<imgW;i++){
				myShift[i] = (int)(scaleFactor*(Math.sin(i*periodFactor+waveShift)));
			}
		}

		if(useSineShift){
			// Insert new points, shifted a little:
			for(int i=0;i<pointCount;i++){

				pX = posX[i]+(int)myShift[posX[i]];
				pY = posY[i]+(int)myShift[posY[i]];
				index = (pY*imgW)+pX;

				if(index>=0 && index <pixMax){ // Check boundaries
					pixCur[index] = pointCol[i];
					setPoints[index] = 1;
				}
			}
		}else{
			// Insert new points at current position (no sine shift):
			for(int i=0;i<pointCount;i++){

				pX = posX[i];
				pY = posY[i];
				index = (pY*imgW)+pX;

				if(index>=0 && index <pixMax){ // Check boundaries
					pixCur[index] = pointCol[i];
					setPoints[index] = 1;
				}
			}

		}

		// Blur:
		// ---------------------------------------------------------------------------
		if(useBlur){
			index = imgW+1;
			pixMax = pixCur.length-imgW;
			while(index<pixMax){

				i1 = index-imgW;
				i2 = index-1;
				i3 = index+1;
				i4 = index+imgW;

				r =  (pixCur[i1])    &0xFF;
				r += (pixCur[i2])    &0xFF;
				r += (pixCur[i3])    &0xFF;
				r += (pixCur[i4])    &0xFF;

				g =  (pixCur[i1]>>8) &0xFF;
				g += (pixCur[i2]>>8) &0xFF;
				g += (pixCur[i3]>>8) &0xFF;
				g += (pixCur[i4]>>8) &0xFF;

				b =  (pixCur[i1]>>16)&0xFF;
				b += (pixCur[i2]>>16)&0xFF;
				b += (pixCur[i3]>>16)&0xFF;
				b += (pixCur[i4]>>16)&0xFF;

				r>>=2;
				g>>=2;
				b>>=2;

				pixCur[index] = (r)|(g<<8)|(b<<16);
				index++;

			}
		}
		// ---------------------------------------------------------------------------

		// Update waveshift:
		waveShift+=waveShiftSpeed;


		// -- Finished! --
	}

	public void update(Graphics g){
		if(!stop){
			g.drawImage(bb,5,5,null);
		}
	}

	public void paint(Graphics g) {
		// Nothing..
	}

	public void run(){
		boolean finishedCred = false;
		int credCount = credSplit.length;
		int curCred = 0;

		long t1=0;
		long t2=0;
		int frameTime = (int)(1000/targetFPS);
		int sleepTime = 0;

		// The main loop.
		while(!stop){
			t1 = System.currentTimeMillis();


			// Main Stuff:
			// -----------------------------------

			finishedCred = movePoints();		// Update the point positions
			drawPoints();						// 'Render' the points to the pixel array
			memSrc.newPixels(0,0,imgW,imgH);	// Update image

			// Check whether the current Cred is finished:
			if(finishedCred){

				if(curCred>(credCount-2)){
					//finished = true;
					curCred=-1;
				}

				// Pause a little:
				long time1=0, time2=0;
				long time3=0;
				long sleepTime2=0;
				time1 = System.currentTimeMillis();
				while((time2-time1)<morphDelay){
					time2 = System.currentTimeMillis();

					drawPoints();						// 'Render' the points to the pixel array
					memSrc.newPixels(0,0,imgW,imgH);	// Update image
					this.repaint();

					time3 = System.currentTimeMillis();
					if((time3-time2)<frameTime){
						sleepTime2 = frameTime-(time3-time2);
					}else{
						sleepTime2 = 1;
					}

					try{
						myThread.sleep(sleepTime2);
					}catch(InterruptedException e){
						// Do nothing.
					}

				}

				// Init with new Cred:
				curCred++;
				newCred(credSplit[curCred]); // Initialize with new Cred string

			}

			this.repaint();
			// -----------------------------------



			// Timing Stuff:
			// -----------------------------------
			t2 = System.currentTimeMillis();
			if((t2-t1)<frameTime){
				sleepTime = frameTime-(int)(t2-t1);
			}else{
				sleepTime = 1;
			}
			try{
				myThread.sleep(sleepTime);
			}catch(InterruptedException e){
				// Do nothing :)
			}
			// -----------------------------------
		}

		if(this.destroy){
			// Finished.
			// Clean up memory:
			posX = null;
			posY = null;
			destX = null;
			destY = null;
			finPoint = null;
			pointCol = null;
			pixCur = null;
			bb = null;
			imgText = null;
			memSrc = null;
			System.gc();
		}
	}



	public void getParams(){
		String strVal=new String("");
		Integer IntVal=new Integer(0);
		Float FltVal=new Float(0);
		int intVal=0;
		float fltVal=0;

		IntVal = getIntParam("width");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal > 5 && intVal < 2000){
				imgW = intVal;
			}
		}

		IntVal = getIntParam("height");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal > 5 && intVal < 1000){
				imgH = intVal;
			}
		}

		IntVal = getIntParam("targetFPS");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal > 1 && intVal < 500){
				targetFPS = intVal;
			}
		}

		IntVal = getIntParam("morphDelayMs");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal >= 0 && intVal < 60000){
				morphDelay = intVal;
			}
		}

		IntVal = getHexParam("backColor");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal >=0 && intVal < 16777216){
				backColor = new Color(intVal);
			}
		}

		IntVal = getHexParam("textColor");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal >=0 && intVal < 16777216){
				fontColor = new Color(intVal);
			}
		}

		IntVal = getIntParam("fontSize");
		if(IntVal!=null){
			intVal = IntVal.intValue();
			if(intVal > 3 && intVal < 200){
				fontSize = intVal;
			}
		}

		FltVal = getFloatParam("sineShiftSpeed");
		if(FltVal!=null){
			fltVal = FltVal.floatValue();
			if(fltVal > 5 && fltVal < 1000){
				waveShiftSpeed = fltVal;
			}
		}

		FltVal = getFloatParam("sinePeriodFactor");
		if(FltVal!=null){
			fltVal = FltVal.floatValue();
			if(fltVal >= 0 && fltVal < 100){
				periodFactor = fltVal;
			}
		}

		FltVal = getFloatParam("sineScaleFactor");
		if(FltVal!=null){
			fltVal = FltVal.floatValue();
			if(fltVal >= 0 && fltVal < 100){
				scaleFactor = fltVal;
			}
		}

		strVal = getStrParam("useBlur");
		if(strVal!=null){
			useBlur = (strVal.toLowerCase().equals("true"));
		}

		strVal = getStrParam("useSineShift");
		if(strVal!=null){
			useSineShift = (strVal.toLowerCase().equals("true"));
		}

		strVal = getStrParam("fontName");
		if(strVal!=null){
			fontName = strVal;
		}

		// Get the text to display:
		strVal = getStrParam("displayText");
		if(strVal!=null){
			StringTokenizer st = new StringTokenizer(strVal,"|");
			credSplit = new String[st.countTokens()];
			int index=0;
			while(st.hasMoreTokens()){
				credSplit[index] = st.nextToken();
				index++;
			}
		}

	}



	public Integer getIntParam(String paramName){
		Integer val= new Integer(0);
		try{
			val = new Integer(Integer.parseInt(getParameter(paramName)));
		}catch(Exception e){
			return null;
		}
		return val;
	}

	public Float getFloatParam(String paramName){
		Float val=new Float(0);
		try{
			val = new Float(Float.parseFloat(getParameter(paramName)));
		}catch(Exception e){
			return null;
		}
		return val;
	}

	public Integer getHexParam(String paramName){
		Integer val= new Integer(0);
		try{
			val = new Integer(Integer.parseInt(getParameter(paramName),16));
		}catch(Exception e){
			return null;
		}
		return val;
	}

	public String getStrParam(String paramName){
		String par = getParameter(paramName);
		if(par==null || par==""){
			return null;
		}else{
			return par;
		}
	}
}

Back to ParticleText

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Avaya DevConnect Center
 Service Component Architecture/Service Data Objects Solution Center
 Intel Go Parallel Portal
 Internet.com eBook Library
 IBM Software Construction Toolbox
 Microsoft RIA Development Center
 Destination .NET
XML error: not well-formed (invalid token) at line 53
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

Red Hat Takes on HPC Market, Microsoft
Python's New Release Bridges the Gap
No Flash Seen on iPhone Horizon
Apple Yields to Complaints Over iPhone NDA
Microsoft Shows Some Ankle With Visual Studio
Gentoo Linux Cancels Distribution
It's Official: Windows 7 at PDC, WinHEC
Oracle Keeps Building on Spoils From BEA
Intel, Oracle Head For 'The Cloud'
Oracle Focuses on Grid, Developer Tools

eCryptfs: Single-File Encryption in Linux
CCXML in Action: A CCXML Auto Attendant
Ballmer: Current Woes Won't Halt Tech, Microsoft
Microsoft Uses VMworld to Hype Its Hypervisor
Microsoft Charges Ahead in Virtualization
Microsoft Shows Some Ankle With Visual Studio
Top 5 Reasons to Adopt SQL Server 2008
Make Application Development Easy With Software Plus Services
SharePoint Applied: 10 Things You Wish They Had Told You?Part 2
Introducing Zend_Search_Lucene

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
Avaya Article: Call Control XML - Powerful, Standards-Based Call Control
Internet.com eBook: The Pros and Cons of Outsourcing
Go Parallel Article: Scalable Parallelism with Intel(R) Threading Building Blocks
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Go Parallel Article: Getting Started with TBB on Windows
HP eBook: Storage Networking , Part 1
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Go Parallel Video: Intel(R) Threading Building Blocks: A New Method for Threading in C++
HP Video: Is Your Data Center Ready for a Real World Disaster?
Microsoft Partner Portal Video: Microsoft Gold Certified Partners Build Successful Practices
HP On Demand Webcast: Virtualization in Action
Go Parallel Video: Performance and Threading Tools for Game Developers
Rackspace Hosting Center: Customer Videos
Intel vPro Developer Virtual Bootcamp
HP Disaster-Proof Solutions eSeminar
HP On Demand Webcast: Discover the Benefits of Virtualization
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Microsoft Download: Silverlight 2 Software Development Kit Beta 2
30-Day Trial: SPAMfighter Exchange Module
Red Gate Download: SQL Toolbelt
Iron Speed Designer Application Generator
Microsoft Download: Silverlight 2 Beta 2 Runtime
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
IBM IT Innovation Article: Green Servers Provide a Competitive Advantage
Microsoft Article: Expression Web 2 for PHP Developers--Simplify Your PHP Applications
Featured Algorithm: Intel Threading Building Blocks - parallel_reduce
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES