P7b: GUI Version
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class EventHandler extends WindowAdapter {
Frame f;
public EventHandler(Frame f) {this.f=f;}
public void windowClosing(WindowEvent e) {
f.dispose();
System.exit(0);
}
}
class Gui extends Frame implements MouseMotionListener, MouseListener {
String[][] fields=null;
chess board=null;
final int field_size=50;
final int num_fields=8;
final int x_offset=30;
final int y_offset=80;
final Font def_font=new Font("Helvetica", Font.BOLD, 14);
Dimension off_dimension=null;
Image off_image=null;
Graphics off_graphics=null;
boolean piece_dragged=false;
int drag_start_pos_x=-1;
int drag_start_pos_y=-1;
final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
MenuBar menubar=CreateMenuBar();
Dialog error_dlg=null, add_dlg=null;
Image bishop, king, knight, rook, queen;
public Gui(String[][] B) {
Toolkit tk=Toolkit.getDefaultToolkit();
fields=B;
board=new chess(fields);
setTitle("Chess P7b Problem");
addWindowListener(new EventHandler(this));
setBackground(Color.white);
addMouseMotionListener(this);
addMouseListener(this);
setMenuBar(menubar);
setSize(2*x_offset + num_fields*field_size+20, y_offset + num_fields*field_size+40);
bishop=tk.getImage("Bishop.gif");
king=tk.getImage("King.gif");
knight=tk.getImage("Knight.gif");
rook=tk.getImage("Rook.gif");
queen=tk.getImage("Queen.gif");
}
public void update(Graphics g) {
Dimension d=getSize();
if(off_graphics == null ||
d.width != off_dimension.width ||
d.height != off_dimension.height) {
off_dimension=d;
off_image=createImage(d.width, d.height);
off_graphics=off_image.getGraphics();
}
//Erase the previous image.
off_graphics.setColor(getBackground());
off_graphics.fillRect(0, 0, d.width, d.height);
off_graphics.setColor(Color.black);
off_graphics.setFont(def_font);
DrawEmptyBoard(off_graphics);
DrawThreatenedFields(off_graphics, Color.red);
DrawPieces(off_graphics);
g.drawImage(off_image, 0, 0, this);
}
public void paint(Graphics g) {
update(g);
}
/** Draws the empty board, no pieces on it yet, just grid lines */
void DrawEmptyBoard(Graphics g) {
int x=x_offset, y=y_offset;
for(int i=0; i < num_fields; i++) {
for(int j=0; j < num_fields; j++) { // draws 1 row
g.drawRect(x, y, field_size, field_size);
x+=field_size;
}
g.drawString(""+ (num_fields-i), x+20, y+field_size/2+5); // draw vert. description (1-8)
y+=field_size;
x=x_offset;
}
// Draw horizontal field descriptions (a-h)
x=x_offset + field_size/2 - 5;
y=y_offset + num_fields * field_size + 20;
for(int i=0; i < num_fields; i++) {
int c=('A' + i);
g.drawString("" + (char)c, x, y);
x+=field_size;
}
}
/** Draws all threatened fields in the list in the given color */
void DrawThreatenedFields(Graphics g, Color c) {
int xpos, ypos;
Color old_col=g.getColor();
g.setColor(c);
for(int x=0; x < num_fields; x++) {
for(int y=0; y < num_fields; y++) {
xpos=GetGraphicalXPos(x);
ypos=GetGraphicalYPos(y);
if(board.getThreat(y, x))
g.fillRect(xpos+1, ypos+1, field_size-2, field_size-2);
}
}
g.setColor(old_col);
}
void DrawPieces(Graphics g) {
int xpos, ypos;
String name=null;
for(int x=0; x < num_fields; x++) {
for(int y=0; y < num_fields; y++) {
name=board.getPiece(y, x);
if(name.length() > 0) {
xpos=GetGraphicalXPos(x);
ypos=GetGraphicalYPos(y);
DrawPiece(g, xpos, ypos, name);
}
}
}
}
void DrawPiece(Graphics g, int x, int y, String name) {
if(name.equals("B") || name.equals("b")) {
if(bishop != null)
g.drawImage(bishop, x+5, y+5, field_size-9, field_size-9, this);
else
g.drawString(name, x+20, y+30);
return;
}
if(name.equals("K") || name.equals("k")) {
if(king != null)
g.drawImage(king, x+5, y+5, field_size-9, field_size-9, this);
else
g.drawString(name, x+20, y+30);
return;
}
if(name.equals("Kn") || name.equals("kn")) {
if(knight != null)
g.drawImage(knight, x+5, y+5, field_size-9, field_size-9, this);
else
g.drawString(name, x+20, y+30);
return;
}
if(name.equals("R") || name.equals("r")) {
if(rook != null)
g.drawImage(rook, x+5, y+5, field_size-9, field_size-9, this);
else
g.drawString(name, x+20, y+30);
return;
}
if(name.equals("Q") || name.equals("q")) {
if(queen != null)
g.drawImage(queen, x+5, y+5, field_size-9, field_size-9, this);
else
g.drawString(name, x+20, y+30);
return;
}
g.drawString("?", x+20, y+30);
}
void AddPiece(int x, int y, String name) {
if(!board.onBoard(x, y)) {
Error("Position " + x + ", " + y + " not valid");
return;
}
y=num_fields - y -1;
fields[y][x]=name;
board=new chess(fields);
repaint();
}
void MovePiece(int x, int y, int dst_x, int dst_y) {
String piece_name=board.getPiece(y, x);
if(x == dst_x && y == dst_y)
return;
if(piece_name.length() > 0) {
fields[dst_y][dst_x]=piece_name;
fields[y][x]="";
board=new chess(fields);
}
}
void ClearBoard() {
for(int x=0; x < num_fields; x++)
for(int y=0; y < num_fields; y++)
fields[x][y]="";
board=new chess(fields);
repaint();
}
/* ----------------- Interface MouseMotionListener ----------------------------- */
public void mouseDragged(MouseEvent e) {
int new_x=e.getX();
int new_y=e.getY();
int new_pos_x=ComputeLogicalXPos(new_x);
int new_pos_y=ComputeLogicalYPos(new_y);
if(piece_dragged)
repaint();
}
public void mouseMoved(MouseEvent e) {
}
/* ------------- End of Interface MouseMotionListener -------------------------- */
/* ---------------------- Interface MouseListener ------------------------------ */
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
int new_x=e.getX();
int new_y=e.getY();
int new_pos_x=ComputeLogicalXPos(new_x);
int new_pos_y=ComputeLogicalYPos(new_y);
if(new_pos_x >= 0 && new_pos_y >= 0) {
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
drag_start_pos_x=new_pos_x;
drag_start_pos_y=new_pos_y;
piece_dragged=true;
}
}
public void mouseReleased(MouseEvent e) {
int new_x=e.getX();
int new_y=e.getY();
int new_pos_x=ComputeLogicalXPos(new_x);
int new_pos_y=ComputeLogicalYPos(new_y);
setCursor(Cursor.getDefaultCursor());
if(piece_dragged)
MovePiece(drag_start_pos_x, drag_start_pos_y, new_pos_x, new_pos_y);
drag_start_pos_x=-1;
drag_start_pos_y=-1;
piece_dragged=false;
repaint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
/* ------------------- End of Interface MouseListener -------------------------- */
int GetGraphicalXPos(int xpos) {
return x_offset + (xpos * field_size);
}
int GetGraphicalYPos(int ypos) {
return y_offset + (ypos * field_size);
}
/** Returns row based on graphical x position */
int ComputeLogicalXPos(int x) {
if(x < x_offset || x > (x_offset + num_fields * field_size))
return -1;
return (int)((x-x_offset)/field_size);
}
/** Returns column based on graphical y position */
int ComputeLogicalYPos(int y) {
if(y < y_offset || y > (y_offset + num_fields * y_offset))
return -1;
return (y-y_offset)/field_size;
}
MenuBar CreateMenuBar() {
MenuBar ret=new MenuBar();
Menu file=new Menu("File");
MenuItem quit=new MenuItem("Quit");
MenuItem add_piece=new MenuItem("Add Piece...");
MenuItem remove_all=new MenuItem("Remove All Pieces");
ret.setFont(def_font2);
ret.add(file);
file.add(add_piece);
file.add(remove_all);
file.addSeparator();
file.add(quit);
add_piece.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
AddPieceDialog();
repaint();
}
});
remove_all.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClearBoard();
repaint();
}
});
quit.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(1);
}
});
return ret;
}
public void Error(String msg) {
Button ok=new Button("Ok");
Label l=new Label(msg);
error_dlg=new Dialog(this, msg, true);
error_dlg.setLocation(90, 150);
error_dlg.setSize(420, 100);
error_dlg.setLayout(new BorderLayout());
error_dlg.setFont(def_font2);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
error_dlg.dispose();
}
});
error_dlg.add("Center", l);
error_dlg.add("South", ok);
error_dlg.show();
}
int String2XPos(String s) {
char c;
String pos;
pos=s.toLowerCase();
c=pos.charAt(0);
return c - 'a';
}
int String2YPos(String s) {
char c;
String pos;
pos=s.toLowerCase();
c=pos.charAt(1);
return c - '1';
}
boolean CheckPos(String s) {
char first, second;
String pos;
if(s == null || s.length() != 2)
return false;
pos=s.toLowerCase();
first=pos.charAt(0);
second=pos.charAt(1);
if(first < 'a' || first > 'h' || second < '1' || second > '8')
return false;
return true;
}
public void AddPieceDialog() {
Label piece_type=new Label("Type:");
Label pos=new Label("Position:");
Button ok=new Button("Ok");
Button cancel=new Button("Cancel");
final Choice piece_choice=new Choice();
final TextField pos_field=new TextField(2);
add_dlg=new Dialog(this, "Add a chess piece", true);
add_dlg.setLayout(new GridLayout(0,2 ));
add_dlg.setLocation(100, 100);
add_dlg.setSize(200, 130);
add_dlg.setFont(def_font2);
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String pos_text=pos_field.getText();
String type_text=piece_choice.getSelectedItem();
int pos_x, pos_y;
if(CheckPos(pos_text) == false) {
Error("Invalid position " + pos_text);
return;
}
pos_x=String2XPos(pos_text);
pos_y=String2YPos(pos_text);
if(type_text.equals("Bishop"))
AddPiece(pos_x, pos_y, "B");
else if(type_text.equals("King"))
AddPiece(pos_x, pos_y, "K");
else if(type_text.equals("Knight"))
AddPiece(pos_x, pos_y, "Kn");
else if(type_text.equals("Queen"))
AddPiece(pos_x, pos_y, "Q");
else if(type_text.equals("Rook"))
AddPiece(pos_x, pos_y, "R");
else
Error("Type " + type_text + " is not known !");
add_dlg.dispose();
}
});
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
add_dlg.dispose();
}
});
piece_choice.add("Bishop");
piece_choice.add("King");
piece_choice.add("Knight");
piece_choice.add("Queen");
piece_choice.add("Rook");
add_dlg.add(piece_type);
add_dlg.add(piece_choice);
add_dlg.add(pos);
add_dlg.add(pos_field);
add_dlg.add(ok);
add_dlg.add(cancel);
add_dlg.show();
}
}
public class P7b {
public static void main(String args[]) {
String[][] B = {
{"" , "" , "" , "" , "" , "" , "" , "" },
{"" , "Kn" , "" , "" , "" , "" , "" , "" },
{"" , "" , "" , "K" , "" , "" , "" , "B"},
{"" , "R" , "" , "" , "" , "B" , "" , "" },
{"" , "Kn" , "" , "" , "" , "" , "" , "" },
{"" , "" , "" , "" , "" , "" , "" , "" },
{"" , "" , "" , "" , "" , "" , "" , "" },
{"" , "" , "" , "R" , "" , "" , "" , "Q"}
};
Gui d = new Gui(B);
d.setSize(600,600);
d.setLocation(0,75);
d.setTitle("Chess");
d.show();
d.toFront();
}
}