home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JSAMPLES.Z / Chessboard.java < prev    next >
Text File  |  1998-05-08  |  35KB  |  1,061 lines

  1. /*
  2.  * Copyright (c) 1997-1998 Borland International, Inc. All Rights Reserved.
  3.  * 
  4.  * This SOURCE CODE FILE, which has been provided by Borland as part
  5.  * of a Borland product for use ONLY by licensed users of the product,
  6.  * includes CONFIDENTIAL and PROPRIETARY information of Borland.  
  7.  *
  8.  * USE OF THIS SOFTWARE IS GOVERNED BY THE TERMS AND CONDITIONS 
  9.  * OF THE LICENSE STATEMENT AND LIMITED WARRANTY FURNISHED WITH
  10.  * THE PRODUCT.
  11.  *
  12.  * IN PARTICULAR, YOU WILL INDEMNIFY AND HOLD BORLAND, ITS RELATED
  13.  * COMPANIES AND ITS SUPPLIERS, HARMLESS FROM AND AGAINST ANY CLAIMS
  14.  * OR LIABILITIES ARISING OUT OF THE USE, REPRODUCTION, OR DISTRIBUTION
  15.  * OF YOUR PROGRAMS, INCLUDING ANY CLAIMS OR LIABILITIES ARISING OUT OF
  16.  * OR RESULTING FROM THE USE, MODIFICATION, OR DISTRIBUTION OF PROGRAMS
  17.  * OR FILES CREATED FROM, BASED ON, AND/OR DERIVED FROM THIS SOURCE
  18.  * CODE FILE.
  19.  */
  20. //
  21. // Chessboard.java
  22. //
  23.  
  24. package borland.samples.apps.chess.client.board;
  25.  
  26. import java.awt.event.*;
  27. import java.net.URL;
  28. import java.awt.*;
  29. import java.awt.image.*;
  30. import java.util.ResourceBundle;
  31.  
  32. public class Chessboard extends Canvas implements MouseMotionListener, MouseListener, Runnable
  33. {
  34.   ResourceBundle res = ResourceBundle.getBundle("borland.samples.apps.chess.client.board.Res");
  35.   boolean animate = true;
  36.   boolean badTimeToStopThread = false;
  37.   boolean mouseActive = false;
  38.   boolean blackOnTop = true;
  39.   boolean blackGoesOnTop = false;
  40.   boolean retryImage = true;
  41.   boolean isLive ; //Chessboard enabled  state
  42.   boolean imageLoadError = false;
  43.   boolean init = false ;
  44.   boolean initfailed = false;
  45.   private Color darkSquareColor;
  46.   private Color lightSquareColor;
  47.   ActionListener listener;
  48.   Image iBoard;
  49.   Image iBackground;
  50.   Image promoteWhite;
  51.   Image promoteBlack;
  52.   Image iAnimationBackground;
  53.   Image iPiece[] ;
  54.   Image iPiecemask[];
  55.   FilteredImageSource masksource[];
  56.   int offset[] ;
  57.   int endrank;
  58.   int startrank;
  59.   int endfile;
  60.   int startfile;
  61.   Thread timer = null;
  62.   Boardsquares squareColor;
  63.   Boardsquares prevpos;
  64.   Boardsquares pieceColor;
  65.   Boardsquares updateArray;
  66.   public static final int LIGHTSQUARE = 0;
  67.   public static final int DARKSQUARE = 16;
  68.   public static final int BLACKPIECE = 8;
  69.   public static final int WHITEPIECE = 0;
  70.   public static final int PAWN   = 1;
  71.   public static final int KNIGHT = 2;
  72.   public static final int BISHOP = 3;
  73.   public static final int ROOK   = 4;
  74.   public static final int QUEEN  = 5;
  75.   public static final int KING   = 6;
  76.   static final String [] file = {"a","b","c","d","e","f","g","h"};
  77.   String initstring = res.getString("Loading_Chessboard");
  78.   String message = "Initialization failed";
  79.   int xoffset;
  80.   int yoffset;
  81.   MediaTracker tracker;
  82.   int p;
  83.   int xincrement;
  84.   int yincrement;
  85.   int xOldMouse;
  86.   int yOldMouse;
  87.   int pointbx = 0;
  88.   int pointby = 0;
  89.   int finalPiece;
  90.   MoveTuple tuple;
  91.   Font boldfont;
  92.   long currentTime = 0;
  93.   private URL boardURL = null;
  94.   private String boardPath = "" ;
  95.  
  96.   public Chessboard ()  {
  97.     try {
  98.       addMouseMotionListener(this);
  99.       addMouseListener(this);
  100.       darkSquareColor = Color.blue;
  101.       lightSquareColor = Color.lightGray;
  102.       boldfont    = new Font("Dialog",Font.BOLD,10) ;
  103.       squareColor = new Boardsquares();
  104.       prevpos     = new Boardsquares();
  105.       pieceColor  = new Boardsquares();
  106.       updateArray = new Boardsquares();
  107.       int i;
  108.       int j;
  109.       offset = new int[8];
  110.       offset[1] = 35;
  111.       iPiece = new Image[32];
  112.       masksource = new FilteredImageSource[16]  ;
  113.       iPiecemask = new Image[16];
  114.       for(j=0;j<8;j=j+2) {
  115.         for(i=0;i<8;i=i+2) {
  116.             squareColor.assign(j+1,i+1,DARKSQUARE);
  117.           squareColor.assign(j+1,i,LIGHTSQUARE);
  118.           squareColor.assign(j,i,DARKSQUARE);
  119.           squareColor.assign(j,i+1,LIGHTSQUARE);
  120.         }
  121.       }
  122.       for(j=0;j<8;j++) {
  123.         prevpos.assign(j,1,PAWN);
  124.         prevpos.assign(j,6,PAWN);
  125.         for(i=0;i<2;i++)  {
  126.             pieceColor.assign(j,i,WHITEPIECE);
  127.           pieceColor.assign(j,i+6,BLACKPIECE);
  128.         }
  129.       }
  130.       prevpos.assign(0,0,ROOK);
  131.       prevpos.assign(1,0,KNIGHT);
  132.       prevpos.assign(2,0,BISHOP);
  133.       prevpos.assign(3,0,QUEEN);
  134.       prevpos.assign(4,0,KING);
  135.       prevpos.assign(5,0,BISHOP);
  136.       prevpos.assign(6,0,KNIGHT);
  137.       prevpos.assign(7,0,ROOK);
  138.       prevpos.assign(0,7,ROOK);
  139.       prevpos.assign(1,7,KNIGHT);
  140.       prevpos.assign(2,7,BISHOP);
  141.       prevpos.assign(3,7,QUEEN);
  142.       prevpos.assign(4,7,KING);
  143.       prevpos.assign(5,7,BISHOP);
  144.       prevpos.assign(6,7,KNIGHT);
  145.       prevpos.assign(7,7,ROOK);
  146.     }
  147.     catch (Exception e) {
  148.       message = e.toString()  ;
  149.       e.printStackTrace();
  150.       initfailed = true;
  151.     }
  152.   }
  153.  
  154.   public Boardsquares getPiecePosition() {
  155.     return prevpos;
  156.   }
  157.  
  158.   public Boardsquares getColorPosition() {
  159.     return pieceColor;
  160.   }
  161.  
  162.   // java.awt.Component method
  163.   public Dimension getPreferredSize() {
  164.     if (offset[1] > 12)   {
  165.       System.err.println("Board preferred Size =(" +  offset[1] + "*8)+12");
  166.       return new Dimension((offset[1] * 8) + 12, (offset[1] * 8) + 12);
  167.     }  
  168.     else
  169.       return new Dimension(292, 292);
  170.   }
  171.  
  172.   public void setImageName(String boardPath) {
  173.     this.boardPath = boardPath;
  174.     try {
  175.       setImageURL(new URL(boardPath));
  176.     }
  177.     catch (Exception e) {
  178.       System.err.println("setImagePath " + e);
  179.     }
  180.   }
  181.  
  182.   public String getImageName() {
  183.     return boardPath;
  184.   }
  185.  
  186.   public void setImageURL(URL boardURL) {
  187.     this.boardURL = boardURL;
  188.     setImage(getToolkit().getImage(boardURL));
  189.   }
  190.  
  191.   public URL getImageURL() {
  192.     return boardURL;
  193.   }
  194.   public void addNotify() {
  195.   //we have been added to a living, breathing  window! if our image has already been set
  196.   //now we can actually take that image and chop it up into little pieces to make our pieces
  197.     super.addNotify();
  198.     if (retryImage)  {
  199.       retryImage = false;
  200.       setImage(iBoard);
  201.     }
  202.   }
  203.  
  204.   public Image getImage() {
  205.     return iBoard;
  206.   }
  207.  
  208.   public synchronized void  setImage(Image iPieces){
  209.     try{
  210.       if (iPieces == null)  {
  211.         System.err.println("setImage - image is null");
  212.         return;
  213.       }
  214.       //need a peer to manipulate images, so remember what to do and wait patiently for addNotify() to happen
  215.       if (retryImage) {
  216.         iBoard = iPieces;
  217.         return;
  218.       }
  219.       //init = false;
  220.       System.err.println("Chessboard.setImage...");
  221.       tracker = new MediaTracker(this);
  222.       tracker.addImage(iPieces,0);
  223.       tracker.waitForAll();
  224.       //System.out.println("done waiting for image...");
  225.       offset[0] = 0;
  226.       int squareSize = iPieces.getWidth(this) / 6;
  227.       //System.out.println("Square width=" + offset[1]);
  228.       if (squareSize < 10) {
  229.         System.out.println("This image is too small.");
  230.         return;
  231.       }
  232.       offset[1] = squareSize;
  233.       int i;
  234.       for (i=2;i < 8;i++)  {
  235.         offset[i] = offset[1] * i;
  236.       }
  237.       initstring = CVS.LOADING_PIECES_;
  238.  
  239.       ImageFilter tfilter = new Transparent();
  240.       MediaTracker trackr ;
  241.       trackr  = new MediaTracker(this);
  242.       FilteredImageSource  mask = new FilteredImageSource(iPieces.getSource(),
  243.                                                     tfilter);
  244.       iPieces = createImage(mask);
  245.       trackr.addImage(iPieces,0);
  246.  
  247.       try {
  248.         initstring = CVS.LOADING_BLACK_PIECE;
  249.         trackr.waitForID(0);
  250.         initstring = CVS.LOADING_WHITE_PIECE;
  251.         //System.out.println("waitForAll did not crash...  " );
  252.       }
  253.       catch (Exception e){
  254.         System.out.println("waitForAll failed ");
  255.        e.printStackTrace();
  256.       }
  257.  
  258.       for (i=0;i<32;i++) {
  259.         iPiece[i] = createImage(offset[1],offset[1]);
  260.       }
  261.        for (i=0;i<16;i++) {
  262.         iPiecemask[i] = createImage(offset[1],offset[1]);
  263.       }
  264.       //System.out.println("create maskimages ");
  265.       Graphics gPiece;
  266.       //pieces
  267.       //pawns
  268.       CropImageFilter crop = new CropImageFilter(offset[5],offset[0],offset[1],offset[1]);
  269.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  270.       iPiecemask[PAWN+WHITEPIECE] = createImage(mask);
  271.       trackr.addImage(iPiecemask[PAWN+WHITEPIECE],1);
  272.       crop = new CropImageFilter(offset[5],offset[1],offset[1],offset[1]);
  273.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  274.       iPiecemask[PAWN+BLACKPIECE] = createImage(mask);
  275.       trackr.addImage(iPiecemask[PAWN+BLACKPIECE],1);
  276.       //knights
  277.       crop = new CropImageFilter(offset[1],offset[0],offset[1],offset[1]);
  278.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  279.       iPiecemask[KNIGHT+WHITEPIECE] = createImage(mask);
  280.       trackr.addImage(iPiecemask[KNIGHT+WHITEPIECE],1);
  281.       crop = new CropImageFilter(offset[1],offset[1],offset[1],offset[1]);
  282.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  283.       iPiecemask[KNIGHT+BLACKPIECE] = createImage(mask);
  284.       trackr.addImage(iPiecemask[KNIGHT+BLACKPIECE],1);
  285.       //bishops
  286.       crop = new CropImageFilter(offset[2],offset[0],offset[1],offset[1]);
  287.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  288.       iPiecemask[BISHOP+WHITEPIECE] = createImage(mask);
  289.       trackr.addImage(iPiecemask[BISHOP+WHITEPIECE],1);
  290.       crop = new CropImageFilter(offset[2],offset[1],offset[1],offset[1]);
  291.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  292.       iPiecemask[BISHOP+BLACKPIECE] = createImage(mask);
  293.       trackr.addImage(iPiecemask[BISHOP+BLACKPIECE],1);
  294.       //rooks
  295.       crop = new CropImageFilter(offset[0],offset[0],offset[1],offset[1]);
  296.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  297.       iPiecemask[ROOK+WHITEPIECE] = createImage(mask);
  298.       trackr.addImage(iPiecemask[ROOK+WHITEPIECE],1);
  299.       crop = new CropImageFilter(offset[0],offset[1],offset[1],offset[1]);
  300.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  301.       iPiecemask[ROOK+BLACKPIECE] = createImage(mask);
  302.       trackr.addImage(iPiecemask[ROOK+BLACKPIECE],1);
  303.       //queens
  304.       crop = new CropImageFilter(offset[3],offset[0],offset[1],offset[1]);
  305.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  306.       iPiecemask[QUEEN+WHITEPIECE] = createImage(mask);
  307.       trackr.addImage(iPiecemask[QUEEN+WHITEPIECE],1);
  308.       crop = new CropImageFilter(offset[3],offset[1],offset[1],offset[1]);
  309.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  310.       iPiecemask[QUEEN+BLACKPIECE] = createImage(mask);
  311.       trackr.addImage(iPiecemask[QUEEN+BLACKPIECE],1);
  312.       //kings
  313.       crop = new CropImageFilter(offset[4],offset[0],offset[1],offset[1]);
  314.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  315.       iPiecemask[KING+LIGHTSQUARE+WHITEPIECE] = createImage(mask);
  316.       trackr.addImage(iPiecemask[KING+WHITEPIECE],1);
  317.  
  318.       crop = new CropImageFilter(offset[4],offset[1],offset[1],offset[1]);
  319.       mask = new FilteredImageSource(iPieces.getSource(),crop);
  320.       iPiecemask[KING+LIGHTSQUARE+BLACKPIECE] = createImage(mask);
  321.       trackr.addImage(iPiecemask[KING+BLACKPIECE],1);
  322.  
  323.       int ImageWidth  = offset[1]*8;
  324.       int ImageHeight = ImageWidth;
  325.       iBoard = createImage(ImageWidth + 12,ImageWidth + 12);
  326.       iBackground = createImage(offset[1],offset[1]);
  327.       iAnimationBackground = createImage(offset[1],offset[1]);
  328.       initstring = CVS.LOADING_MASKS_;
  329.       try {
  330.         initstring = CVS.LOADING_BLACK_PIECE;
  331.         trackr.waitForID(1);
  332.         initstring = CVS.LOADING_WHITE_PIECE;
  333.         //System.out.println("waitForAll did not crash  " );
  334.       }
  335.       catch (Exception e){
  336.         System.out.println("waitForAll failed ");
  337.        e.printStackTrace();
  338.       }
  339.       repaint();
  340.       setLightSquareColor(lightSquareColor);
  341.       setDarkSquareColor(darkSquareColor);
  342.       promoteBlack = createImage(offset[1]*4,offset[1]);
  343.       promoteWhite = createImage(offset[1]*4,offset[1]);
  344.       if (promoteBlack == null)  {
  345.         System.err.println("Chessboard.SetImage promoteBlack=null " + offset[1]);
  346.         return;
  347.       }
  348.       System.err.println("Chessboard.SetImage build initial position");
  349.       Graphics   g = promoteBlack.getGraphics();
  350.       g.drawImage(iPiece[ROOK+LIGHTSQUARE+BLACKPIECE],0,0,this);
  351.       g.translate(offset[1],0);
  352.       g.drawImage(iPiece[KNIGHT+DARKSQUARE+BLACKPIECE],0,0,this);
  353.       g.translate(offset[1],0);
  354.       g.drawImage(iPiece[BISHOP+LIGHTSQUARE+BLACKPIECE],0,0,this);
  355.       g.translate(offset[1],0);
  356.       g.drawImage(iPiece[QUEEN+DARKSQUARE+BLACKPIECE],0,0,this);
  357.       g.dispose();
  358.       g = promoteWhite.getGraphics();
  359.       g.drawImage(iPiece[ROOK+DARKSQUARE+WHITEPIECE],0,0,this);
  360.       g.translate(offset[1],0);
  361.       g.drawImage(iPiece[KNIGHT+LIGHTSQUARE+WHITEPIECE],0,0,this);
  362.       g.translate(offset[1],0);
  363.       g.drawImage(iPiece[BISHOP+DARKSQUARE+WHITEPIECE],0,0,this);
  364.       g.translate(offset[1],0);
  365.       g.drawImage(iPiece[QUEEN+LIGHTSQUARE+WHITEPIECE],0,0,this);
  366.       g.dispose();
  367.  
  368.       setSize(getPreferredSize());
  369.       init = true;
  370.       setPosition(prevpos,pieceColor);
  371.       drawBorder();
  372.       //System.err.println("Chessboard.SetImage last repaint");
  373.       initstring = CVS.CREATING_INITIAL;
  374.       repaint();
  375.       //System.err.println("Chessboard.SetImage return from repaint");
  376.     }
  377.     catch (Exception e) {
  378.       e.printStackTrace();
  379.       System.err.println("Chessboard.init " + e.toString());
  380.       repaint(0);
  381.     }
  382.     //System.err.println("Chessboard.init end");
  383.   }
  384.  
  385.   public void setLightSquareColor(Color color) {
  386.     lightSquareColor = color;
  387.     if (iBoard != null) {
  388.       Graphics square = iPiece[0].getGraphics();
  389.       fillSquare(square,lightSquareColor);
  390.       square.dispose();
  391.       square = iPiece[8].getGraphics();
  392.       fillSquare(square,lightSquareColor);
  393.       square.dispose();
  394.       for (int i=1; i< 7;i++) {
  395.         for (int j=0; j <= BLACKPIECE;j=j+BLACKPIECE) {
  396.           // System.out.println("draw piece " + i + ","+ j);
  397.           Graphics g = iPiece[i+j+LIGHTSQUARE].getGraphics();
  398.           g.drawImage(iPiece[LIGHTSQUARE],0,0,this);
  399.           g.drawImage(iPiecemask[i+j],0,0,this);
  400.           g.dispose();
  401.         }
  402.       }
  403.       if (init)
  404.         repaint();
  405.     }
  406.   }
  407.  
  408.   public Color getLightSquareColor() {
  409.     return lightSquareColor;
  410.   }
  411.  
  412.   private void fillSquare(Graphics square,Color color) {
  413.      square.setColor(color);
  414.      square.fillRect(0,0,offset[1],offset[1]);
  415.   }
  416.  
  417.   public void setDarkSquareColor(Color color) {
  418.     darkSquareColor = color;
  419.     if (iBoard != null) {
  420.       Graphics square = iPiece[16].getGraphics();
  421.       fillSquare(square,darkSquareColor);
  422.       square.dispose();
  423.       square = iPiece[24].getGraphics();
  424.       fillSquare(square,darkSquareColor);
  425.       square.dispose();
  426.       for (int i=1; i< 7;i++) {
  427.         for (int j=0; j <= BLACKPIECE;j=j+BLACKPIECE) {
  428.           // System.out.println("draw piece " + i + ","+ j);
  429.           Graphics g = iPiece[i+j+DARKSQUARE].getGraphics();
  430.           g.drawImage(iPiece[16],0,0,this);
  431.           g.drawImage(iPiecemask[i+j],0,0,this);
  432.           g.dispose();
  433.         }
  434.       }
  435.       if (init)
  436.         repaint();
  437.     }
  438.   }
  439.  
  440.   public Color getDarkSquareColor() {
  441.     return darkSquareColor;
  442.   }
  443.  
  444.   void drawBorder() {
  445.     if (iBoard == null)
  446.       return;
  447.     Graphics gBoard = iBoard.getGraphics();
  448.     if (gBoard == null)
  449.       return;
  450.     blackGoesOnTop = blackOnTop;
  451.     gBoard.setColor(getBackground());
  452.     int imagewidth = offset[1] * 8;
  453.     gBoard.fillRect(imagewidth,0,12,imagewidth + 12);
  454.     gBoard.fillRect(0,imagewidth,imagewidth,12);
  455.     gBoard.setColor(Color.black );
  456.     gBoard.setFont(boldfont);
  457.     int xoffset = (offset[1] -  8) / 2;
  458.     int yoffset = (offset[1] + 12) / 2;
  459.     if (blackOnTop) {
  460.       for (int i=0;i<8;i++)  {
  461.         gBoard.drawString(String.valueOf(8-i),imagewidth + 2,(i * offset[1]) + yoffset);
  462.       }
  463.       for (int i=0;i<8;i++) {
  464.         gBoard.drawString(file[i],(i * offset[1]) + xoffset,imagewidth + 10);
  465.       }
  466.     }
  467.     else {
  468.       for (int i=0;i<8;i++) {
  469.         gBoard.drawString(String.valueOf(1+i),imagewidth + 2,(i * offset[1]) + yoffset);
  470.       }
  471.       for (int i=0;i<8;i++) {
  472.         gBoard.drawString(file[7-i],(i * offset[1]) + xoffset,imagewidth + 10);
  473.       }
  474.     }
  475.     gBoard.dispose();
  476.   }
  477.  
  478.   public void setPosition(){
  479.     setPosition(prevpos,pieceColor);
  480.   }
  481.  
  482.   public void setPosition(Boardsquares piecearray,Boardsquares colorarray)  {
  483.     if (init) {
  484.     int rank = 0;
  485.     int file = 0;
  486.     int xoff = offset[1];
  487.     int yoff = offset[1];
  488.     int i = 0;
  489.     int newxoff;
  490.     int newyoff;
  491.     int squarecount = 0;
  492.     int pointax=0;
  493.     int pointay = 0;
  494.     xincrement = 0;
  495.     yincrement =0;
  496.     updateArray.init(prevpos);
  497.     updateArray.add(pieceColor);
  498.     updateArray.subtract(piecearray);
  499.     updateArray.subtract(colorarray);
  500.     for (rank = 0 ; rank < 8 ; rank++) {
  501.       for (file = 0 ; file < 8 ; file++) {
  502.         if (updateArray.value(file,rank) != 0) {
  503.           if (squarecount < 2) {
  504.             if (squarecount == 0) {
  505.               pointax = file;
  506.               pointay = rank;
  507.             }
  508.             else {
  509.               pointbx = file;
  510.               pointby = rank;
  511.             }
  512.           }
  513.           squarecount++;
  514.         }
  515.       }
  516.     }
  517.     boolean doAnimation  = false;
  518.     if (squarecount == 2 && timer == null) {
  519.       if (piecearray.value(pointax,pointay) > 0 &&
  520.           prevpos.value(pointbx,pointby) > 0 ) {
  521.         file = pointax;
  522.         rank = pointay;
  523.         pointay = pointby;
  524.         pointax = pointbx;
  525.         pointbx = file;
  526.         pointby = rank;
  527.       }
  528.       file = pointax;
  529.       rank = pointay;
  530.       if (blackOnTop) {
  531.            xincrement = 2 *(pointbx - pointax); //left is 0, right is 7
  532.            yincrement = 2 *(pointay - pointby); //top is 7 bottom is 0
  533.         newxoff = file*xoff;
  534.         newyoff =  yoff*7 - (rank*yoff);
  535.       }
  536.       else  {
  537.            xincrement = 2 *(pointax - pointbx); //left is 7, right is 0
  538.            yincrement = 2 *(pointby - pointay); //top is 0 bottom is 7
  539.         newxoff = xoff*7 -(file*xoff);
  540.            newyoff = rank*yoff;
  541.       }
  542.       //set initial background to new square contents
  543.       synchronized (this) {
  544.         p = squareColor.value(file,rank) +
  545.             piecearray.value(file,rank) +
  546.             colorarray.value(file,rank);
  547.         Graphics gAnimationBackground = iAnimationBackground.getGraphics();
  548.         gAnimationBackground.drawImage(iPiece[p],0,0,this);
  549.         gAnimationBackground.dispose();
  550.         p = pieceColor.value(file,rank) +
  551.             prevpos.value(file,rank);
  552.         finalPiece = piecearray.value(pointbx,pointby) +
  553.                      colorarray.value(pointbx,pointby) ;
  554.          xoffset = newxoff;
  555.         yoffset = newyoff;
  556.         if (colorarray.value(pointbx,pointby) == pieceColor.value(file,rank) && piecearray.value(pointbx,pointby) > 0) {
  557.           timer = new Thread(this);
  558.           timer.start();
  559.           doAnimation = true;
  560.         }
  561.       }
  562.     }
  563.     if (!doAnimation) {
  564.       synchronized (this) {
  565.         Graphics gBoard = iBoard.getGraphics();
  566.         xoffset = 0;
  567.         yoffset = 0;
  568.         for (rank = 0 ; rank < 8 ; rank++) {
  569.             for (file = 0 ; file < 8 ; file++) {
  570.             if (squarecount == 0 || updateArray.value(file,rank) != 0 || timer != null) {
  571.               if (blackOnTop)  {
  572.                 newxoff = file*xoff;
  573.                 newyoff =  yoff*7 - (rank*yoff);
  574.               }
  575.               else {
  576.                 newxoff = xoff*7 -(file*xoff);
  577.                 newyoff = rank*yoff;
  578.               }
  579.               i = squareColor.value(file,rank) +
  580.                   colorarray.value(file,rank) +
  581.                   piecearray.value(file,rank);
  582.               gBoard.translate(newxoff - xoffset,newyoff-yoffset);
  583.               gBoard.drawImage(iPiece[i],0,0,this);
  584.               xoffset = newxoff;
  585.               yoffset = newyoff;
  586.         }
  587.           }
  588.         }
  589.         gBoard.dispose();
  590.       }
  591.  
  592.       if (timer != null) {
  593.         synchronized(timer) {
  594.           if (badTimeToStopThread)
  595.             System.out.println("How can it stop now?");
  596.           animate = false;
  597.           timer.notify();
  598.          timer = null;
  599.         }
  600.       }
  601.       repaint();
  602.     }
  603.     }
  604.     prevpos.init(piecearray);
  605.     pieceColor.init(colorarray);
  606.   }
  607.  
  608.   public void stop() {
  609.     if (timer != null)
  610.       timer.stop();
  611.     System.out.println("Chessboard.stop was called");
  612.     timer = null;
  613.   }
  614.  
  615.   //java.awt.Runnable method
  616.   public void run() {
  617.     int i;
  618.     int myy;
  619.     int myx;
  620.     animate = true;
  621.     Graphics gBoard = iBoard.getGraphics();
  622.     Graphics gAnimationBackground  = iAnimationBackground.getGraphics();
  623.  
  624.     try {
  625.       if (isLive = isEnabled())
  626.         setEnabled(false); //so stray mouse clicks don't screw us over
  627.       int  absx = xincrement;
  628.       int absy = yincrement;
  629.       if (absx < 0)
  630.           absx = -absx;
  631.       if (absy < 0)
  632.           absy = -absy;
  633.       absx = absx + absy;
  634.       int timedelay = 10;
  635.       if (absx > 2)
  636.           timedelay = 15;
  637.       myx = xoffset;
  638.       myy = yoffset;
  639.       gBoard.translate(xoffset,yoffset);
  640.       int endingXOffset = xoffset + offset[1]*xincrement/2;
  641.       int endingYOffset = yoffset + offset[1]*yincrement/2;
  642.  
  643.       boolean skip = false;
  644.       int loopcount = offset[1] /2;
  645.       if (p > finalPiece)
  646.         p = finalPiece;  //promoted pieces moving backwards move as pawns
  647.       int endingpiece = finalPiece + squareColor.value(pointbx,pointby) ;
  648.       int piece = p;
  649.       for (i=0;i<loopcount;i++) {
  650.         if (iPiecemask[p] == null)
  651.           System.out.println("Chessboard.run iPiecemask[" + p + "] null ");
  652.         int translatex;
  653.         int translatey;
  654.         synchronized (this) {
  655.           if (animate) {
  656.             badTimeToStopThread = true;
  657.             translatex = myx - xoffset ;
  658.             translatey = myy - yoffset ;
  659.             if (translatex + translatey != 0) {
  660.               gBoard.translate(translatex,translatey);
  661.               xoffset = xoffset + translatex;
  662.               yoffset = yoffset + translatey;
  663.             }
  664.             myx = xoffset + xincrement;
  665.             myy = yoffset + yincrement;
  666.               gBoard.drawImage(iAnimationBackground,0,0,this);
  667.             gAnimationBackground.drawImage(iBoard,-1*myx,-1*myy,this);
  668.             translatex = myx-xoffset;
  669.             translatey = myy-yoffset;
  670.             gBoard.translate(translatex,translatey);
  671.             xoffset = myx;
  672.             yoffset = myy;
  673.             gBoard.drawImage(iPiecemask[piece],0,0,this);
  674.             badTimeToStopThread = false;
  675.           }
  676.           else
  677.             break;
  678.         }
  679.         if ( skip == false) {
  680.           repaint();
  681.           try {Thread.sleep(timedelay);}
  682.           catch (InterruptedException e){}
  683.           catch (Exception e){System.err.println("Chessbord.run "+ e.toString());}
  684.         }
  685.         if (timedelay ==  10)
  686.           if (skip == false)
  687.             skip = true;
  688.           else
  689.             skip = false;
  690.       }
  691.       if (animate) {
  692.         synchronized (this) {
  693.           int translatex = myx - xoffset ;
  694.           int translatey = myy - yoffset ;
  695.           if (translatex + translatey != 0) {
  696.             xoffset = xoffset + translatex;
  697.             yoffset = yoffset + translatey;
  698.             gBoard.translate(translatex,translatey);
  699.           }
  700.           gBoard.drawImage(iAnimationBackground,0,0,this);
  701.           gBoard.translate(endingXOffset - xoffset,endingYOffset - yoffset);
  702.           xoffset = endingXOffset;
  703.           yoffset = endingYOffset;
  704.           gBoard.drawImage(iPiece[endingpiece],0,0,this);
  705.         }
  706.       }
  707.       if (isLive)
  708.         setEnabled(true);
  709.     }
  710.     catch(Exception x ) {System.err.println("Chessboard.run "+ x.toString());}
  711.     catch(ThreadDeath x) {
  712.       if (badTimeToStopThread)
  713.         System.out.println("You picked the wrong time to give up running");
  714.       else
  715.         System.err.println("ThreadDeath");
  716.       if (isLive)
  717.         setEnabled(true);
  718.       throw x;
  719.     }
  720.     gBoard.dispose();
  721.     gAnimationBackground.dispose();
  722.     xoffset = 0;
  723.     yoffset = 0;
  724.     repaint();
  725.     timer = null;
  726.   }
  727.  
  728.   //java.awt.Component method
  729.   public void update(Graphics g) {
  730.     paint(g);
  731.   }
  732.  
  733.   //java.awt.Component method
  734.   public void paint(Graphics g) {
  735.     //System.err.println("Chessboard.paint " + init + " initfailed=" + initfailed);
  736.     if (init == true && initfailed == false) {
  737.       if (blackOnTop ^ blackGoesOnTop) {
  738.         drawBorder();
  739.       }
  740.       g.drawImage(iBoard,0,0,this);
  741.     }
  742.     else {
  743.       System.err.println("Chessboard.paint " + init + " initfailed=" + initfailed + " " + boardURL);
  744.  
  745.       g.setColor(getBackground());
  746.       g.fillRect(0,0,280,280);
  747.       g.setColor(Color.blue );
  748.       g.drawString(initstring,10,135);
  749.       //The designers first call to setImage never seems to work
  750.       //if (retryImage && init == false && initfailed == false && boardURL != null)
  751.       //  setImageURL(boardURL);
  752.     }
  753.   }
  754.  
  755.   // java.awt.MouseMotionListener method
  756.   public void mouseDragged(MouseEvent mev)  {
  757.     if (mouseActive == true) {
  758.       currentTime = System.currentTimeMillis();
  759.       int squareRadius = offset[1]/2;  //fudge factor so image is centered on the cursor
  760.       int x = mev.getX() - squareRadius;
  761.       int y = mev.getY() - squareRadius;
  762.       //System.out.println("mouse dragged");
  763.       synchronized (this) {
  764.         Graphics gBoard = iBoard.getGraphics();
  765.         gBoard.translate(xOldMouse,yOldMouse);
  766.         gBoard.drawImage(iBackground,0,0,this);
  767.         gBoard.translate(x-xOldMouse,y-yOldMouse);
  768.         xOldMouse = x;
  769.         yOldMouse = y;
  770.         Graphics gBackground = iBackground.getGraphics();
  771.         gBackground.drawImage(iBoard,-1*(xOldMouse),-1*(yOldMouse),this);
  772.         gBoard.drawImage(iPiecemask[p],0,0,this);
  773.         gBoard.dispose();
  774.         gBackground.dispose();
  775.       }
  776.       repaint();
  777.     }
  778.     return ;
  779.   }
  780.  
  781.   // java.awt.MouseMotionListener method
  782.   public void mouseMoved(MouseEvent e){}
  783.  
  784.   // java.awt.MouseListener method
  785.   public void mouseClicked(MouseEvent e){}
  786.  
  787.   // java.awt.MouseListener method
  788.   public void mouseExited(MouseEvent e){}
  789.  
  790.   // java.awt.MouseListener method
  791.   public void mouseEntered(MouseEvent e){}
  792.  
  793.   // java.awt.MouseListener method
  794.   public void  mousePressed(MouseEvent mev)     {
  795.     int x = mev.getX();
  796.     int y = mev.getY();
  797.     int squareSize = offset[1] ;
  798.     //System.out.println("mouse pressed");
  799.     int mousex = (x / squareSize) * squareSize;
  800.     int mousey = (y / squareSize) * squareSize;
  801.     if (x/squareSize > 7 || y /squareSize > 7)  {
  802.       //System.out.println("click out of bounds" + squareSize + "," + x  + "," + y);
  803.       return ;
  804.     }
  805.     synchronized (this) {
  806.       xoffset = mousex ;
  807.       yoffset = mousey;
  808.       xOldMouse = xoffset;
  809.       yOldMouse = yoffset;
  810.       if (blackOnTop) {
  811.         startfile = x/squareSize;
  812.         startrank =  7 - (y/squareSize);
  813.       }
  814.       else {
  815.         startfile = 7 - (x/squareSize);
  816.         startrank = y/squareSize;
  817.       }
  818.       p = prevpos.value(startfile,startrank) ;
  819.       if (p > 0) {
  820.         p = p + pieceColor.value(startfile,startrank);
  821.         Graphics gBackground = iBackground.getGraphics();
  822.         gBackground.drawImage(iPiece[squareColor.value(startfile,startrank)],0,0,this);
  823.         gBackground.dispose();
  824.         mouseActive = true;
  825.       }
  826.     }
  827.     return ;
  828.   }
  829.  
  830.   // java.awt.MouseListener method
  831.   public void mouseReleased(MouseEvent mev){
  832.     if (!mouseActive)
  833.        return ;
  834.      //System.out.println("mouse released");
  835.     int x = mev.getX();
  836.     int y = mev.getY();
  837.     int piecevalue =0;
  838.     int piececolor =0;
  839.     synchronized (this) {
  840.       Graphics gBoard = iBoard.getGraphics();
  841.       if (mouseActive) {
  842.         gBoard.translate(xOldMouse,yOldMouse);
  843.         gBoard.drawImage(iBackground,0,0,this);
  844.       }
  845.       else {
  846.         xOldMouse = 0;
  847.         yOldMouse = 0;
  848.       }
  849.       int squareSize = offset[1] ;
  850.       int mousex = (x / squareSize) * squareSize;
  851.       int mousey = (y / squareSize) * squareSize;
  852.       if (blackOnTop) {
  853.         endfile = x/squareSize;
  854.         endrank =  7 - (y/squareSize);
  855.       }
  856.       else {
  857.         endfile = 7 - (x/squareSize);
  858.         endrank = y/squareSize;
  859.       }
  860.       if (startrank != endrank || startfile != endfile) {
  861.         if (endrank < 0 || endrank > 7 || endfile < 0 ||
  862.             endfile > 7) {
  863.           endrank = startrank;
  864.           endfile = startfile;
  865.           if (blackOnTop) {
  866.             mousex = startfile * squareSize;
  867.             mousey = (7 - startrank) * squareSize;
  868.           }
  869.           else {
  870.             mousex = (7 - startfile) * squareSize;
  871.             mousey = startrank * squareSize;
  872.           }
  873.         }
  874.         if (startrank < 0 || startrank > 7)
  875.            System.out.println("Startrank =" + startrank + "??");
  876.         if (startfile < 0 || startfile > 7)
  877.            System.out.println("Startfile =" + startfile + "??");
  878.  
  879.         piecevalue = prevpos.value(startfile,startrank);
  880.         piececolor = pieceColor.value(startfile,startrank);
  881.         prevpos.assign(startfile,startrank,0);
  882.         pieceColor.assign(startfile,startrank,0);
  883.         prevpos.assign(endfile,endrank,piecevalue);
  884.         pieceColor.assign(endfile,endrank,piececolor);
  885.       }
  886.       gBoard.translate(mousex - xOldMouse,mousey - yOldMouse);
  887.       int w =  squareColor.value(endfile,endrank) + p;
  888.       gBoard.drawImage(iPiece[w],0,0,this);
  889.       gBoard.dispose();
  890.     }
  891.     repaint();
  892.     if (startrank != endrank || startfile != endfile) {
  893.       broadcast(piecevalue,piececolor);
  894.     }
  895.     mouseActive = false;
  896.     return ;
  897.   }
  898.  
  899.   void broadcast(int piecevalue,int piececolor) {
  900.     boolean showPromotionDialog = false;
  901.     PromotionDialog dDialog = null;
  902.     try {
  903.       if (piecevalue == PAWN  &&
  904.          (endrank == 0 || endrank == 7)) {
  905.         if (piececolor == WHITEPIECE && startrank ==6) {
  906.           showPromotionDialog = true;
  907.           dDialog = new PromotionDialog(getFrame(this),promoteWhite,this);
  908.         }
  909.         else
  910.           if (piececolor == BLACKPIECE && startrank ==1) {
  911.             showPromotionDialog = true;
  912.             dDialog = new PromotionDialog(getFrame(this),promoteBlack,this);
  913.           }
  914.       }
  915.       if (showPromotionDialog){
  916.         //System.out.println("Show promotion dialog");
  917.         dDialog.pack();
  918.         dDialog.setLocation(360,300);
  919.         dDialog.setVisible(true);
  920.         //System.out.println(" promotion dialog Shown");
  921.       }
  922.       else {
  923.         tuple = new MoveTuple();
  924.         tuple.pieceValue = prevpos.value(endfile,endrank);
  925.         tuple.newpieceValue = tuple.pieceValue;
  926.         tuple.pieceColor = pieceColor.value(endfile,endrank);
  927.         tuple.fromFile = startfile;
  928.         tuple.fromRank = startrank;
  929.         tuple.toFile = endfile;
  930.         tuple.toRank = endrank;
  931.         handleActionEvent(new ActionEvent(this,1,null));
  932.       }
  933.     }
  934.     catch (Exception e) {
  935.       e.printStackTrace();
  936.     }
  937.   }
  938.  
  939.   public static Frame getFrame(Component theComponent) {
  940.     Component currParent = theComponent;
  941.     Frame theFrame = null;
  942.     while (currParent != null)  {
  943.       if (currParent instanceof Frame){
  944.         theFrame = (Frame) currParent;
  945.         break;
  946.       }
  947.       currParent = currParent.getParent();
  948.     }
  949.     return theFrame;
  950.   }
  951.  
  952.   public synchronized void addActionListener(ActionListener l) {
  953.     if (listener == null)
  954.       listener = l;
  955.   }
  956.  
  957.   public synchronized void removeActionListener(ActionListener l) {
  958.     listener = null;
  959.   }
  960.  
  961.   public ActionListener getActionListener() {
  962.     return listener;
  963.   }
  964.  
  965.   protected  void handleActionEvent(ActionEvent ae) {
  966.     if (getActionListener() != null) {
  967.       getActionListener().actionPerformed(ae);
  968.     }
  969.   }
  970.  
  971.   public MoveTuple getTuple() {
  972.     return tuple;
  973.   }
  974.  
  975.   void promote(int piecesub) {
  976.     tuple = new MoveTuple();
  977.     switch (piecesub)    {
  978.       case 3:
  979.         tuple.newpieceValue = QUEEN;
  980.         break;
  981.       case 1:
  982.         tuple.newpieceValue = KNIGHT;
  983.         break;
  984.       case 0:
  985.         tuple.newpieceValue = ROOK;
  986.         break;
  987.       case 2:
  988.         tuple.newpieceValue = BISHOP;
  989.         break;
  990.     }
  991.     tuple.pieceValue = prevpos.value(endfile,endrank);
  992.     tuple.pieceColor = pieceColor.value(endfile,endrank);
  993.     tuple.fromFile = startfile;
  994.     tuple.fromRank = startrank;
  995.     tuple.toFile = endfile;
  996.     tuple.toRank = endrank;
  997.     handleActionEvent(new ActionEvent(this,1,null));
  998.   }
  999.  
  1000.   public boolean isBlackOnTop() {
  1001.     return blackOnTop;
  1002.   }
  1003.  
  1004.   public boolean switchOrientation()  {
  1005.     blackOnTop = !blackOnTop;
  1006.     int squareSize = offset[1];
  1007.     int rank,file,newxoff,newyoff,i;
  1008.     int xoffset = 0;
  1009.     int yoffset = 0;
  1010.     Graphics gBoard = iBoard.getGraphics();
  1011.     for (rank = 0 ; rank < 8 ; rank++) {
  1012.       for (file = 0 ; file < 8 ; file++) {
  1013.         if (blackOnTop) {
  1014.           newxoff = file*squareSize;
  1015.           newyoff =  squareSize*7 - (rank*squareSize);
  1016.         }
  1017.         else {
  1018.           newxoff = squareSize*7 -(file*squareSize);
  1019.           newyoff = rank*squareSize;
  1020.         }
  1021.         i = squareColor.value(file,rank) +
  1022.             pieceColor.value(file,rank) +
  1023.             prevpos.value(file,rank);
  1024.         synchronized (this) {
  1025.           gBoard.translate(newxoff - xoffset  ,newyoff-yoffset );
  1026.           gBoard.drawImage(iPiece[i], 0, 0, this);
  1027.           xoffset = newxoff;
  1028.           yoffset = newyoff;
  1029.         }
  1030.       }
  1031.     }
  1032.     gBoard.dispose();
  1033.     repaint();
  1034.     return blackOnTop;
  1035.   }
  1036. }
  1037.  
  1038. class Transparent extends RGBImageFilter
  1039. {
  1040.   int backgroundPixel = 0xFF00FF00;
  1041.   public Transparent() {
  1042.     canFilterIndexColorModel = false;
  1043.   }
  1044.  
  1045.   public int filterRGB(int x, int y,int rgb) {
  1046.     try{
  1047.       if (x == 0 && y ==0)
  1048.         backgroundPixel = rgb;
  1049.       if (backgroundPixel == rgb)
  1050.         rgb = rgb & 0x00FFFFFF  ;
  1051.     }
  1052.     catch(Exception e) {
  1053.       e.printStackTrace();
  1054.       //System.out.println("filterRGB "  + e.toString());
  1055.     }
  1056.     return rgb;
  1057.   }
  1058. }
  1059.  
  1060.  
  1061.