Image Puzzle  This example shows a simple image puzzle. User needs to 
reconstruct the image in the left hand side by following
the small original image shown in the right side. The rendered puzzle is as shown below,
	 
    
   
  
   
    
package  com.bethecoder.tutorials.gameprog; import  java.awt.Image; import  java.awt.event.ActionEvent; import  java.awt.event.ActionListener; import  java.util.List; import  javax.swing.Icon; import  javax.swing.ImageIcon; import  javax.swing.JButton; import  javax.swing.JFrame; import  com.bethecoder.tutorials.random.Shuffle; public class  Puzzle  extends  JFrame  implements  ActionListener {    private static final  long  serialVersionUID =  387273093383621728L ;    private static final  int  PUZZLE_ROWS =  3 ;    private static final  int  PUZZLE_COLS =  4 ;       private  JButton  [][]  splitImgs =  null ;    private  JButton originalImg =  null ;    public  Puzzle ( String name ){      super ( name ) ;                    this .setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE ) ;      this .getContentPane () .setLayout ( null ) ;      /**       * Add Original Image       */      Image image=  new  ImageIcon ( "images/original.jpg" ) .getImage () ;         originalImg =  new  JButton ( new  ImageIcon ( image.getScaledInstance ( 120 ,  90 , Image.SCALE_SMOOTH  ))) ;      originalImg.setBounds ( 610 ,  40 ,  120 ,  90 ) ;      this .getContentPane () .add ( originalImg ) ;      /**       * Add Split Images       */      addSplitImage () ;           /**       * Start the title animation.       */      startTilteAnimation ( name ) ;    } //end constructor     private  void  addSplitImage () {      String img =  null ;      ImageIcon icon =  null ;      splitImgs =  new  JButton [ PUZZLE_ROWS ][ PUZZLE_COLS ] ;      List imgVec = Shuffle.shuffle ( 1 ,  12 ) ;           for  ( int  i =  0 ; i < PUZZLE_ROWS; i ++  ) {        for  ( int  j =  0 ; j < PUZZLE_COLS; j ++  ){          img =  "images/" + imgVec.get (( i*PUZZLE_COLS )  + j )  +  ".jpg" ;          icon =  new  ImageIcon ( img ) ;           this .splitImgs [ i ][ j ] = new  JButton () ;          /**           * Show split image, except one button           */          if ( ! ( i== 2 &&j== 3 )) {             this .splitImgs [ i ][ j ] .setIcon ( icon ) ;          }                   /**           * Set split image positions           */          this .splitImgs [ i ][ j ] .setBounds ( j* 144 + 20 , i* 144 + 20 ,  144 ,  144 ) ;          this .splitImgs [ i ][ j ] .addActionListener ( this ) ;          this .getContentPane () .add ( this .splitImgs [ i ][ j ]) ;        }      } //end for    }       private  void  startTilteAnimation ( final  String nam ){      Thread rotateTitleThread =  new  Thread (){        String temp= "" ;        String name=nam;        public  void  run (){          while ( true ){            /**             * Rotate the puzzle application title by one char             */            temp = name.substring ( 0 ,name.length () - 1 ) ;            name = name.substring ( name.length () - 1 ) ;            name +=temp;            Puzzle. this .setTitle ( name ) ;             try  { Thread.sleep ( 180 ) ;  } catch ( Exception e ){  e.printStackTrace () ;  } ;          } //end while        }        } ;            rotateTitleThread.start () ;    } //end of method.    public  void  actionPerformed ( ActionEvent ae ){      for  ( int  i= 0 ; i < PUZZLE_ROWS; i++  ) {        for  ( int  j= 0 ; j <PUZZLE_COLS ; j++ ) {                   if ( ae.getSource ()  ==  this .splitImgs [ i ][ j ]){            Icon clikedImg =  this .splitImgs [ i ][ j ] .getIcon () ;            log ( "In actionPerformed clikedImg :: "  + clikedImg ) ;            checkAndMoveButton ( i, j ) ;           }         }      } //end for              } //end action method    private  void  checkAndMoveButton ( int  row,  int  col ){           JButton curButton =  this .splitImgs [ row ][ col ] ;       JButton swapButton =  null ;              if  ( isSwapAllowed ( swapButton = getTopButton ( row, col ))) {        swapIcon ( curButton, swapButton ) ;      }  else if  ( isSwapAllowed ( swapButton = getBottomButton ( row, col ))) {        swapIcon ( curButton, swapButton ) ;      }  else if  ( isSwapAllowed ( swapButton = getLeftButton ( row, col ))) {        swapIcon ( curButton, swapButton ) ;      }  else if  ( isSwapAllowed ( swapButton = getRightButton ( row, col ))) {        swapIcon ( curButton, swapButton ) ;      }           }       /**     * Swap possible only if the button available and its empty.     *  @param  swapButton     *  @return     */    private  boolean  isSwapAllowed ( JButton swapButton ) {      return  swapButton !=  null  && swapButton.getIcon ()  ==  null ;    }    private  void  swapIcon ( JButton curButton, JButton swapButton ) {           if ( swapButton !=  null  && swapButton.getIcon ()  ==  null ) {                                                         swapButton.setIcon ( curButton.getIcon ()) ;        curButton.setIcon ( null ) ;      }    }    private  JButton getTopButton ( int  row,  int  col ) {      return  getButton ( row -  1 , col ) ;    }       private  JButton getBottomButton ( int  row,  int  col ) {      return  getButton ( row +  1 , col ) ;    }       private  JButton getLeftButton ( int  row,  int  col ) {      return  getButton ( row, col -  1 ) ;    }       private  JButton getRightButton ( int  row,  int  col ) {      return  getButton ( row, col +  1 ) ;    }       private  JButton getButton ( int  row,  int  col ) {           if  ( row <  0  || row >= PUZZLE_ROWS || col <  0  || col >= PUZZLE_COLS ) {        return null ;      }           return this .splitImgs [ row ][ col ] ;      }    public static  void  log ( String msg ) {      System.out.println ( msg ) ;    }       /**     * Start the puzzle.     *  @param  args     */    public static  void  main ( String  []  args ){      try {        String name= " _ , .~   ><##*>  ~. ,  _ ,. ~  \\_sudha_/  ,~  ,~."  +        "   ><$$*> ` ., _.   ><%%*>  ,.  ~ _.~  ` .~ .   ><$$*> " ;          Puzzle p= new  Puzzle ( name ) ;        p.setSize ( 750 , 510 ) ;        p.setLocation ( 20 , 20 ) ;            p.setVisible ( true ) ;        p.setResizable ( false ) ;       } catch ( Exception e ){        e.printStackTrace () ;      }    } //end main } //end class