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();
    }
}