christianix.de

-> Main -> GWT Tutorial -> WebPuzzle.java

package de.christianix.puzzle.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class WebPuzzle implements ClickHandler, EntryPoint {

	private static final String DEFAULT_IMAGE_DIR = "images";
	private static final String IMAGE_BASE_NAME = "tile";
	private static final int XDIM = 6;
	private static final int YDIM = 3;

	private static DialogBox msgbox = null;
	private static Button msgbutton = null;
	private VerticalPanel mainPanel = null;
	private Grid puzzleGrid = null;

	private PuzzleBoard puzzleBoard = null;
	private Image tiles[] = null;

	/**
	 * Entry point method.
	 */
	public void onModuleLoad() {
		mainPanel = new VerticalPanel();
		puzzleGrid = new Grid( YDIM, XDIM );
		puzzleBoard = new PuzzleBoard( YDIM, XDIM );
		tiles = new Image[YDIM*XDIM];

		/* DEBUG output:
		System.out.println( puzzleBoard.toString() );
		System.out.println( "Number permutiations: " + puzzleBoard.permutationCount() );
		*/

		loadTiles();
		placeTiles();

		// Prepare board
		puzzleGrid.addClickHandler( this );
		puzzleGrid.addStyleName("puzzleBoard");
		puzzleGrid.setCellPadding(0);
		puzzleGrid.setCellSpacing(0);

		// Assemble Main panel.
		mainPanel.add(puzzleGrid);

		// Associate the Main panel with the HTML host page.
		RootPanel.get("puzzleTable").add(mainPanel);

		// Setup message box
		msgbox = new DialogBox( true );
		msgbox.setText("Puzzle solved!");
		msgbox.setPopupPosition( mainPanel.getAbsoluteLeft(), mainPanel.getAbsoluteTop() );

		msgbutton = new Button( "Restart" );
		msgbutton.addClickHandler( this );
		msgbox.setWidget( msgbutton );
	}

	protected void loadTiles() {
		final int N = YDIM * XDIM - 1;
		int n = 0;

		for ( int y = 0; y < YDIM; ++y ) {
			for ( int x = 0; x < XDIM; ++x ) {
				if ( n == N ) return;
				this.tiles[n] = new Image( DEFAULT_IMAGE_DIR+"/"+IMAGE_BASE_NAME+"_"+y+"_"+x+".png" );
				++n;
			}
		}
	}

	protected void placeTiles() {
		for ( int y = 0; y < YDIM; ++y ) {
			for ( int x = 0; x < XDIM; ++x ) {
				puzzleGrid.getCellFormatter().setStyleName(y, x, "puzzleTile" );
				int i = puzzleBoard.getTileIndex(y, x);
				if ( i != -1 ) {
					puzzleGrid.setWidget( y, x, this.tiles[i] );
				}
			}
		}
	}

	/**
	 * Move widget in puzzleTable
	 * @param fromX
	 * @param fromY
	 * @param toX
	 * @param toY
	 */
	private void move( int fromX, int fromY, int toX, int toY ) {
		Widget img = puzzleGrid.getWidget( fromY, fromX );
		puzzleGrid.setWidget( fromY, fromX, null );
		puzzleGrid.setWidget( toY, toX, img );
	}

	@Override
	public void onClick( ClickEvent event ) {
		if ( event.getSource() == puzzleGrid ) {
			Cell c = puzzleGrid.getCellForEvent( event );
			int px = c.getCellIndex();
			int py = c.getRowIndex();
			int ex = puzzleBoard.getEmptyX();
			int ey = puzzleBoard.getEmptyY();

			if ( puzzleBoard.moveTile(px, py) ) {
				move( px, py, ex, ey );
			}

			if ( puzzleBoard.permutationCount() == 0 ) {
				msgbox.show();
			}
		}
		else if ( event.getSource() == msgbutton ) {
			msgbox.hide();
			puzzleGrid.clear();
			puzzleBoard.init();
			placeTiles();
		}
	}
}

syntax highlighted by Code2HTML, v. 0.9.1