Package eu.semberal.migmang.graphics

Source Code of eu.semberal.migmang.graphics.MigmangBoardComponent$BoardComponentsEvent

package eu.semberal.migmang.graphics;

import eu.semberal.migmang.enums.GameColor;
import java.awt.event.MouseEvent;

import eu.semberal.migmang.logic.Move;
import eu.semberal.migmang.logic.Board;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import javax.swing.JComponent;
import eu.semberal.migmang.logic.Referee;
import eu.semberal.migmang.logic.MoveContainer;

/**
* Component the board will be painted on. Will also handle event from the user.
*
* @author lukas.sembera
*
*/
public class MigmangBoardComponent extends JComponent {

    private int width, height;
    private int squareWidth;
    private Point topLeftBoardPosition;
    private int pieceRadius;
    private final int boardMargin;
    private Board currentBoard = null;
    GameColor movingColor = null;
    MoveContainer moveContainer = null;
    int movingPiece = -1;
    /**
     * Array of upper left corner point of pieces on the board
     */
    private Point[] piecesTopLeftCorners;

    public void allowMove(GameColor color, MoveContainer container) {
        this.moveContainer = container;
        this.movingColor = color;
    }

    public void setBoard(Board board) {
        this.currentBoard = board;
    }

    public MigmangBoardComponent() {
        topLeftBoardPosition = new Point();
        boardMargin = 50;
        piecesTopLeftCorners = new Point[81];

        BoardComponentsEvent tridaUdalosti = new BoardComponentsEvent();
        this.addMouseListener(tridaUdalosti);
        this.addMouseMotionListener(tridaUdalosti);

    }

    @Override
    public synchronized void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        if (movingPiece == -1) {
            MigmangBoardComponent.this.updatePiecesCoordinates(true);
            MigmangBoardComponent.this.updateBoardVariables(true);
        }


        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g.setColor(Color.GRAY);
        g.fillRect(0, 0, this.getSize().width, this.getSize().height);

        drawBoard(g2d);
        drawCoordinates(g2d);
        if (currentBoard != null) {
            drawPieces(g2d);
        }

        if (movingPiece != -1) {
            drawPossibleMoves(g2d);
        }


    }

    private void drawPieces(Graphics2D g) {
        for (int i = 0; i < 81; i++) {

            if (piecesTopLeftCorners[i] == null) {
                continue;
            }
            if (currentBoard.getSquare(i) != null) {
                g.setColor(currentBoard.getSquare(i) == GameColor.White ? Color.WHITE : Color.BLACK);
                g.fillOval(piecesTopLeftCorners[i].x, piecesTopLeftCorners[i].y, 2 * pieceRadius, 2 * pieceRadius);
                g.setColor(currentBoard.getSquare(i) == GameColor.Black ? Color.WHITE : Color.BLACK);
                g.drawOval(piecesTopLeftCorners[i].x, piecesTopLeftCorners[i].y, 2 * pieceRadius, 2 * pieceRadius);
            }

        }
    }

    private void drawBoard(Graphics2D g) {
        for (int i = 0; i < 64; i++) {
            g.setStroke(new BasicStroke(2));

            int tempX = topLeftBoardPosition.x + (i % 8) * squareWidth;
            int tempY = topLeftBoardPosition.y + (i / 8) * squareWidth;
            g.setColor((i / 8 + i % 8) % 2 == 0 ? Color.RED : Color.YELLOW);
            g.fillRect(tempX, tempY, squareWidth,
                    squareWidth);
            g.setColor(Color.black);

            g.drawRect(tempX, tempY, squareWidth,
                    squareWidth);

        }
    }

    private void drawPossibleMoves(Graphics2D g2d) {
        g2d.setStroke(new BasicStroke(1));
        g2d.setColor(Color.BLACK);
        for (Move t : Referee.getAvailableMoves(currentBoard, movingPiece)) {
            int vykresli = t.getTo();
            g2d.drawOval(topLeftBoardPosition.x + (vykresli % 9) * squareWidth - pieceRadius,
                    topLeftBoardPosition.y + (vykresli / 9) * squareWidth - pieceRadius,
                    2 * pieceRadius,
                    2 * pieceRadius);
        }
    }

    /**
     * Updates variables such as board size, etc. Values are different on each
     * resize
     *
     * @param repaint Whether the board should be repainted
     */
    public void updateBoardVariables(boolean repaint) {

        this.width = this.getSize().width;
        this.height = this.getSize().height;
        this.squareWidth = (Math.min(width, height) - 2 * boardMargin) / 8;
        this.topLeftBoardPosition.x = (width - 8 * squareWidth) / 2;
        this.topLeftBoardPosition.y = (height - 8 * squareWidth) / 2;
        this.pieceRadius = Math.min(squareWidth / 4, 30);
        if (repaint) {
            this.repaint();
        }
    }

    /**
     * Recalculates coordinates of pieces
     *
     * @param repaint Whether the board should be repainted
     */
    public synchronized void updatePiecesCoordinates(boolean repaint) {


        if (currentBoard != null) {
            GameColor s;
            for (int i = 0; i < piecesTopLeftCorners.length; i++) {
                s = currentBoard.getSquare(i);
                int aktX, aktY;
                if (s == null) {
                    piecesTopLeftCorners[i] = null;
                } else {
                    aktX = topLeftBoardPosition.x + (i % 9) * squareWidth;
                    aktY = topLeftBoardPosition.y + (i / 9) * squareWidth;
                    piecesTopLeftCorners[i] = new Point(aktX - pieceRadius, aktY - pieceRadius);
                }

            }
        }

        if (repaint) {
            this.repaint();
        }


    }

    /**
     * Draws coordinates ('A', '1', ...)
     */
    public synchronized void drawCoordinates(Graphics g2d) {
        int h;
        g2d.setFont(new Font("serif", Font.BOLD, h = squareWidth / 2));
        for (int i = 0; i < 9; i++) {
            String s = String.valueOf(i);
            g2d.drawString(s, topLeftBoardPosition.x + squareWidth * i, topLeftBoardPosition.y - 7);
        }

        for (int i = 0; i < 9; i++) {

            char c = (char) ('A' + i);
            String s = String.valueOf(c);
            g2d.drawString(s, topLeftBoardPosition.x - squareWidth / 2,
                    topLeftBoardPosition.y + h / 2 + squareWidth * i);
        }
    }

    /**
     * Events of the board component, will call methods of the main window and
     * notify controller
     */
    private class BoardComponentsEvent extends MouseAdapter {

        /*
         * Difference between point pushed and topleft corner of the piece.
         * Necessary to draw draggin correctly.
         */
        private int diffX, diffY;
        /**
         * How large rectangle will be repainted on move (speed optimization)
         */
        private final int REDRAW_MARGIN = 3;

        @Override
        public void mouseDragged(MouseEvent e) {
            if (movingPiece != -1) {

                piecesTopLeftCorners[movingPiece] = new Point(e.getPoint().x - diffX, e.getPoint().y - diffY);

                MigmangBoardComponent.this.repaint(
                        e.getX() - REDRAW_MARGIN * squareWidth,
                        e.getY() - REDRAW_MARGIN * squareWidth,
                        2 * REDRAW_MARGIN * squareWidth,
                        2 * REDRAW_MARGIN * squareWidth);

            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            if (movingColor == null) {
                return;
            }


            for (int i = 0; i < piecesTopLeftCorners.length; i++) {
                if (currentBoard.getSquare(i) != movingColor) {
                    continue;
                }
                if (new Rectangle(piecesTopLeftCorners[i].x, piecesTopLeftCorners[i].y, 2 * pieceRadius, 2 * pieceRadius).contains(e.getPoint())) {
                    diffX = e.getPoint().x - piecesTopLeftCorners[i].x;
                    diffY = e.getPoint().y - piecesTopLeftCorners[i].y;
                    movingPiece = i;
                    break;
                }


            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {

            if (movingPiece == -1) {
                return;
            }

            for (int i = 0; i < piecesTopLeftCorners.length; i++) {
                if (new Rectangle(topLeftBoardPosition.x + (i % 9) * squareWidth - pieceRadius,
                        topLeftBoardPosition.y + (i / 9) * squareWidth - pieceRadius,
                        2 * pieceRadius,
                        2 * pieceRadius).contains(e.getPoint())) {
                    moveContainer.setMove(new Move(movingPiece, i, movingColor));
                    movingColor = null;
                    movingPiece = -1;
                    return;
                }
            }
            movingColor = null;
            movingPiece = -1;
            /*
             * If not placed on incorrect square, report incorrect move.
             * Controller will then ask for new one.
             */
            moveContainer.setMove(Move.createIncorrectMove());


        }
    }
}
TOP

Related Classes of eu.semberal.migmang.graphics.MigmangBoardComponent$BoardComponentsEvent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.