zurück zur Übersicht

SimpleBoard.java

 
/** 
 * SimpleBoard.java
 *
 * @author Martin Klöckner, Daniel Höpfl
 *
 * @see IOutput
 */

package SpringerPack.Boards;

import SpringerPack.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Point;
import java.awt.FontMetrics;
import java.awt.Font;
import java.awt.Image;
import java.awt.Canvas;
import java.awt.Polygon;

/**
 * This class implements an IOutput conform Board. It's very simple but
 * it provides all functions that are supported by IOutput
 *
 * @see SimpleBoardRed
 * @see IOutput
 */

public class SimpleBoard extends IOutput
{
      /**
       * Size of board in fields
       */
   private int mSize = 9;
      /**
       * Width of Board in pixels
       */
   private int mWidth = -1;
      /**
       * Height of Board in pixels
       */
   private int mHeight = -1;

      /**
       * Calculated size of font to fit all used numbers into fields
       */
   private int mFontSize = -1;

      /**
       * the board we draw
       */
   private Board mBoard = null;

      /**
       * X coordinate of start-field
       */
   private int mStartX = 0;
      /**
       * Y coordinate of start-field
       */
   private int mStartY = 0;

      /**
       * Image we can offscreen-draw to.
       */
   private Image mImg = null;

      /**
       * sets a new size of the board in fields
       *
       * @param inSize   size of board asked for (5 ... 16)
       *
       * @see IOutput#setBoardSize
       */
   public void setBoardSize(int inSize) {
      if(inSize < 5)
         inSize = 5;
      mSize = inSize;

      mFontSize = -1;

      repaint();
   }
   
      /**
       * sets a board to draw
       *
       * @param inBoard   Board to set
       *
       * @see IOutput#setBoard
       * @see Board
       */
   public void setBoard(Board inBoard)
   {
      mBoard = inBoard;
   }

      /**
       * recursion gets one step deeper
       *
       * @param inSourceX      X of the field we have left
       * @param inSourceY      Y of the field we have left
       * @param inDestX      X of the field we jumped to
       * @param inDestY      Y of the field we jumped to
       *
       * @see IOutput#deeper
       */
   public void deeper(int inSourceX, int inSourceY, int inDestX, int inDestY)
   {
      repaint();
   }

      /**
       * recursion gets one step higher
       *
       * @param inSourceX      X of the field we have left
       * @param inSourceY      Y of the field we have left
       * @param inDestX      X of the field we jumped to
       * @param inDestY      Y of the field we jumped to
       *
       * @see IOutput#higher
       */
   public void higher(int inSourceX, int inSourceY, int inDestX, int inDestY)
   {
      repaint();
   }

      /**
       * calculates what field has been clicked
       *
       * @param inClicked      coordinates inside this Component that was
       *                  clicked (0 ... mWidth-1, 0 ... mHeight-1)
       *
       * @return   X/Y-Coordinate of field clicked (if inside board) as Point.
       *         null else.
       *
       * @see IOutput#calcStartField
       */
   public Point calcStartField(Point inClicked)
   {
      int x = inClicked.x;
      x /= mWidth/mSize;

      int y = inClicked.y;
      y /= mHeight/mSize;

      if(x >= mSize ||
         y >= mSize ||
         x < 0 ||
         y < 0)
      {
         return null;
      }
      else
         return new Point(x, y);
   }

      /**
       * set a new starting field
       *
       * @param inX   X coordinate of the field
       * @param inY   Y coordinate of the field
       *
       * @see IOutput#setStart
       */
   public void setStart(int inX, int inY)
   {
      mStartX = inX;
      mStartY = inY;

      setBoard(null);
      repaint();
   }

      /**
       * set a new Image for offscreen-drawing
       *
       * @param inImage   the Image to set
       *               must be big enought to take the whole output area
       *
       * @see IOutput#setImage
       */
   public void setImage(Image inImage) {
      mImg = inImage;
   }

      /**
       * catch the setSize function of java.awt.Component to get the
       * outer size of our drawing-area
       *
       * @param inDim      size of this element
       *
       * @see java.awt.Component#setSize
       */
   public void setSize(java.awt.Dimension inDim) {
      super.setSize(inDim);

      mWidth = inDim.width - 1;
      mHeight = inDim.height - 1;

      mFontSize = -1;

      repaint();
   }

      
   public void update(Graphics inGraphics) {
         // super.update would clear the drawing area
         // since we should not have any childs we leave it out
//      super.update(inGraphics);

         // repaint the board (using offscreen - or not)
      paint(inGraphics);
   }

      /**
       * replaces the default (empty) paint method.
       * Draws offscreen and copies to screen if there is an Image set
       *
       * @param inG   place to draw to
       *
       * @see SimpleBoard#update
       * @see SimpleBoard#setImage
       * @see java.awt.Component#update
       * @see java.awt.Graphics
       */
   public void paint(Graphics inG) {
         // boardsize not set?
      if(mWidth < 0 || mHeight < 0)
         return;

         // by default we draw non-offscreen
      Graphics g = inG;

         // if there is an Image -> draw offscreen
         // we will copy it to the screen later
      if(mImg != null)
         g = mImg.getGraphics();

         // clear background
      g.setColor(getBackground());
      g.fillRect(0, 0, mWidth+1, mHeight+1);

         // calc fontsize
      int fontWidth = 0;
      int fontHeight = 0;
      FontMetrics fontMetrics = null;

      if(mFontSize < 0)
      {
         int width = mWidth/mSize;
         int height = mHeight/mSize;

         mFontSize = 0;
         int step = 64;
         while(step > 1)
         {
            mFontSize += step;

            g.setFont(new Font("Dialog", Font.PLAIN, mFontSize));
            fontMetrics = g.getFontMetrics();
            fontHeight = fontMetrics.getAscent();
            fontWidth = 0;

            int widestNumber = 0;
            for(int i=0; i < 10; i++)
            {
               int thisWidth;
               thisWidth = fontMetrics.stringWidth(new Integer(i).toString());

               if(thisWidth > widestNumber)
                  widestNumber = thisWidth;
            }

            String theNumberStr = new Integer(mSize * mSize).toString();

            fontWidth = theNumberStr.length() * widestNumber;

            if(fontWidth > (width - 4) || fontHeight > height)
            {
               mFontSize -= step;
            }

            step /= 2;
         }

         mFontSize += 1;

         if(mFontSize < 4)
            mFontSize = 4;
      }

         // set calculated font
      g.setFont(new Font("Dialog", Font.PLAIN, mFontSize));
      fontMetrics = g.getFontMetrics();
      fontHeight = fontMetrics.getAscent();

         // calc size of fields
      int width = mWidth/mSize;
      int height = mHeight/mSize;

         // draw all the fields
      for(int y=0; y<mSize; y++)
      {
         for(int x=0; x<mSize; x++)
         {
               // get it chess-colored
            if((x+y) % 2 == 1)
               g.setColor(getWhiteFieldColor());
            else
               g.setColor(getBlackFieldColor());

            g.fillRect(x*width+1, y*height+1, width, height);

               // is there set a board and currend field has been touched?
            if(mBoard != null &&
               mBoard.getXY(x,y) > 0)
            {
                  // write number into the field
               g.setColor(Color.black);
               fontWidth = fontMetrics.stringWidth(new Integer(mBoard.getXY(x,y)).toString());

               g.drawString(new Integer(mBoard.getXY(x,y)).toString(),
                           x*width+2+width/2-fontWidth/2,
                           y*height+height/2+fontHeight/2);
            }

               // mark start-field
            if(   x == mStartX &&
               y == mStartY)
            {
               g.setColor(getStartFieldBorderColor());
               g.drawRect(x*width+1, y*height+1, width-1, height-1);
            }
         }
      }
         // draw a nice rect around it.
      g.setColor(Color.black);
      g.drawRect(0, 0, width*mSize, height*mSize);

         // copy offscreen drawn image to screen
      if(mImg != null)
         inG.drawImage(mImg, 0, 0, this);
   }

      /**
       * function to get the Color of "white" fields
       *
       * @return   Color of "white" fields
       *
       * @see SimpleBoardRed#getWhiteFieldColor
       */
   public Color getWhiteFieldColor()
   {
      return Color.white;
   }

      /**
       * function to get the Color of "black" fields
       *
       * @return   Color of "black" fields
       *
       * @see SimpleBoardRed#getBlackFieldColor
       */
   public Color getBlackFieldColor()
   {
      return Color.lightGray;
   }

      /**
       * function to get the Color of the outline of the startfield
       *
       * @return   Color of startfields border
       *
       * @see SimpleBoardRed#getStartFieldBorderColor
       */
   public Color getStartFieldBorderColor()
   {
      return Color.red;
   }
}

zurück zur Übersicht