home *** CD-ROM | disk | FTP | other *** search
/ BUG 15 / BUGCD1998_06.ISO / aplic / jbuilder / jsamples.z / Chessboard.java < prev    next >
Text File  |  1997-07-15  |  33KB  |  1,019 lines

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