DJ Club data applet
Scrabble Rack Applet
With double buffering and improved painting. Can drag tiles around rack. Cannot move out of rack. Sample - not a real game, but part of GUI.












Can click and drag the letter images. This sample has 4 racks.
Requires java plugin to allow applet to run get it from java or oracle java site.

Preview Source code of applet

package tgk.aplt.scrabl;

import javax.accessibility.AccessibleContext;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

import javax.swing.*;
import javax.swing.event.*;

import java.util.Vector;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.text.*;

import tgk.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.net.*;

/**
 *
 * @author  Tushar Kapila tgkprog@gmail.com http://sel2in.in/
 * Widget for Scrabble Rack
 */
	public class ScrblRack extends Canvas implements Runnable {

		/**
		* defines the space for the border
		*/
		static final Insets insMn = new Insets(0,0,0,0);//Insets(4,4,4,4) //(int top, int left, int bottom, int right)
		static final Insets insAlp = new Insets(0,0,0,0);//(3,3,3,3)


		/**
		* image width
		*/
		int WW = 24;
		int HH = 24;
		int HH_dragx = HH;
		int WW_dragx = WW - 13;

		boolean HH_drag_y_none = true;

		static final Font fnt = new Font("Arial", Font.PLAIN, 15);

		static String urlPath = "./";


		private final Object SYNC_OBJ = new Object();

		boolean repaint_req= true;

		int lastX ;
		int lastY ;

		int place = -1;
		int places[]={0, 1, 2, 3 ,4 ,5, 6};
		boolean changed =false;

		boolean dragging = false;
		boolean pickedUp  = false;

		int numApl = 3;

		FontMetrics fm;
		BufferedImage offScreen, alps[];


		boolean clrCan =true;


		private Polygon polys[];

//.....

		public void update(Graphics g1){
			if(clrCan ){
				super.update(g1);
				clrCan =false;
			}else{
				paint(g1);
			}
		}

		public void paint(Graphics g1){

			//widget background color
			final Color clr = Color.white;//new Color( 238, 233, 191);//Color.blue;//new Color(0, 0, 245)//124, 125, 145
			Graphics2D g  = (Graphics2D  )offScreen.createGraphics();
			Graphics2D g2  = (Graphics2D)g1;

			final int hh_c = getHeight();
			final int ww_c = getWidth();

			g.setColor(clr);
			g.fillRect(0,0, ww_c , hh_c);

			final int xx1 = WW + insAlp.left + insAlp.right;
			for(int i = 0; i < numApl ; i++){
				g.fillRect(insMn.left + (i * ( xx1) ), insMn.top , (xx1 ), HH + insAlp.top + insAlp.bottom);
				if(places[i] > -1 && (!dragging || (place != i))){
					g.drawImage(alps[places[i]], (xx1 * i),  insMn.top + insAlp.top, this);
				}
			}

			/*for border

			g.setColor(new Color(250, 250, 210));
			g.fillRect(0,0, ww_c , insMn.top);
			g.fillRect(0,0, insMn.left , hh_c);
			g.fillRect(ww_c - insMn.right, 0, ww_c , hh_c);
			g.fillRect(0,hh_c - insMn.bottom, ww_c  , hh_c);	*/


			if(dragging){
				if(place >= 0 && place < numApl){
					//g.drawImage(alps[places[place]], Math.max(0, lastX - WW), Math.min(hh_c - HH + 6, lastY), this);
					if(HH_drag_y_none){
						g.drawImage(alps[places[place]], Math.max(0, lastX - WW + WW_dragx ), insMn.top + insAlp.top, this);
					}else{
						g.drawImage(alps[places[place]], Math.max(0, lastX - WW + WW_dragx ), Math.min(hh_c - HH + HH_dragx, lastY), this);
						//u.sl("lastX " + lastX + "drag x " + Math.max(0, lastX - WW + WW_dragx ) + " lastY " + lastY +  " y " + Math.min(hh_c - HH + HH_dragx, lastY) );
					}
				}
			}
			g2.drawImage(offScreen,0 ,0, this);
			changed =false;

		}

		protected void processKeyEvent(KeyEvent e){
			//u.sl(e + " e.getKeyCode() " + e.getKeyCode() + " KeyEvent.VK_J " + KeyEvent.VK_J + " KeyEvent.KEY_PRESSED " + KeyEvent.KEY_PRESSED + " e.getID()  " + e.getID() );
			if((e.getID() | KeyEvent.KEY_PRESSED) == KeyEvent.KEY_PRESSED && KeyEvent.VK_J == e.getKeyCode()){
				//u.sl("Jumble");
				java.util.List l = new ArrayList(numApl);
				int i=0;
				for( i = 0; i < numApl; i++ ){
					l.add(new Integer(places[i]));
				}
				Collections.shuffle(l);
				for( i = 0; i < numApl; i++ ){
					places[i] = ((Integer)l.get(i)).intValue();
				}
				repaint_requested();
			}
		}

		protected void processMouseMotionEvent(MouseEvent e){
			//u.sl(e + " e.getID() == MouseEvent.MOUSE_DRAGGED  " + (e.getID() == MouseEvent.MOUSE_DRAGGED ));
			int i =0;
			boolean has = false;
			lastX = e.getX();
			lastY = e.getY();
			for( i = 0; i < 7 ; i++){
				if(polys[i].contains(e.getX(), e.getY()) ){
					if(i < numApl){
						setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
					}
					has = true;
					break;
				}
			}

			if(pickedUp && (!dragging) && e.getID() == MouseEvent.MOUSE_DRAGGED && has){
				dragging = true;
				place = i;
				changed =true;
				clrCan =true;
				repaint_requested();

				return;

			}
			if(( ((e.getID()  ) == MouseEvent.MOUSE_EXITED || ((e.getID() ) == MouseEvent.MOUSE_ENTERED) && dragging)
			))//|| ((e.getID() ) != MouseEvent.MOUSE_DRAGGED ) && dragging)
			{
				if(has)chkChng(i);
				dragging = false;
				repaint_requested();
			}
			if ( (e.getID()  == MouseEvent.MOUSE_DRAGGED ) && dragging)repaint_requested();


			if(!has)setCursor(Cursor.getDefaultCursor());

		}

		protected void processMouseEvent(MouseEvent e){
			//u.sl(e + " e.getID() == MouseEvent.MOUSE_PRESSED  " + (e.getID() == MouseEvent.MOUSE_PRESSED) );
			lastX = e.getX();
			lastY = e.getY();
			boolean has = false;
			int i = 0;
			for(i = 0; i < 7  ; i++){
				if(polys[i].contains(e.getX(), e.getY())){
					has = true;
					break;
				}
			}

			if(!dragging && e.getID() == MouseEvent.MOUSE_PRESSED && has){
				pickedUp = true;

				return;

			}else if(dragging && e.getID() == MouseEvent.MOUSE_RELEASED ){
				if(has)
				chkChng(i);
				place = i;
				dragging =false;
				changed =true;
				clrCan =true;
				repaint_requested();
			}
			if( e.getID() == MouseEvent.MOUSE_RELEASED ){
				pickedUp = false;
				dragging =false;
			}

			if(dragging)repaint_requested();

		}

		void chkChng(int newIdx ){
			final int oldIdx = place;

			if(oldIdx > -1 && oldIdx != newIdx){
				if(newIdx >= numApl){
					//u.sl("newIdx >= numApl newIdx:" + newIdx);
					newIdx = numApl-1;

				}

				int oldVal = places[oldIdx];
				u.sl( "chng newIdx " + newIdx + " plc " + oldIdx );
				for(int i2 = 0 ;  i2 < 7  ; i2++){
					if(places[i2] > -1){
						u.sl( i2 + " plc " + places[i2]);
					}
				}

				if(newIdx > oldIdx){
					u.sl("newIdx > p change ; oldIdx " + oldIdx + " newIdx " + newIdx);
					for(int i2 =oldIdx;  i2 < (newIdx  ) ; i2++){
						places[i2] = places[i2 + 1];
						u.sl(" i2 " + i2 + " places[i2]  " +  places[i2] );
					}
				}else{
					u.sl(" change > ; oldIdx " + oldIdx + " newIdx " + newIdx);
					for(int i2 = oldIdx ;  i2 > newIdx ; i2--){
						places[i2] = places[i2 - 1];
						u.sl(" i2 " + i2 + " places[i2]  " +  places[i2] );
					}
				}
				places[newIdx] = oldVal  ;//ABC

				for(int i2 = 5 ;  i2 > -1  ; i2--){
					if(places[i2+1] > -1 && places[i2] == -1 ){
						places[i2] = places[i2+1] ;
						places[i2+1] = -1;
					}
				}
				repaint_requested();
				place = -1;
			}

		}


	void repaint_requested(){
		repaint();

	}

	/**
	* To be called by parent before calling #init() with the root URL/ folder of this application
	*/
	public static void setUrlPath (String s){
		urlPath = s + "";
		u.sl("urlPath  " + urlPath );
	}
}




Copyright Tushar Kapila 2007 tgkprog@gmail.com