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();
            }
        }
    }