|
/**
* 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;
}
}
|