Package chesstrainer.ui

Source Code of chesstrainer.ui.CBoard

/*
* Copyright (C) 2014 Tim Declercq <caveman1917@hotmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package chesstrainer.ui;

import chesstrainer.CPosition;
import chesstrainer.Main;
import chesstrainer.util.EPiece;
import chesstrainer.util.ESide;
import chesstrainer.util.ESquare;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.FileInputStream;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import javax.swing.JPanel;

/**
*
* @author Tim Declercq <caveman1917@hotmail.com>
*/
public class CBoard extends JPanel implements MouseListener, MouseMotionListener {
   
    private CPieceSet pieceset;
    private Color darkColor, lightColor, arrowColor, selectedColor;
    private ESide perspective = ESide.WHITE;
    private CPosition position;
    private Set<ESquare> selectedSquares = EnumSet.noneOf(ESquare.class);
    private Set<CArrow> arrows = new HashSet<>();
    private Set<ESquare> blindfoldSquares = EnumSet.noneOf(ESquare.class);
   
    private boolean dragging = false;
    private ESquare draggingSquare = null;
    private int mouseX = 0, mouseY = 0;
   
    private Set<IBoardListener> listeners = new HashSet<>();
   
    private boolean animating = false;
    private ESquare animateFrom = null, animateTo = null;
    private long animateStart, animateEnd;
   
    public CBoard(CPosition position) {
        super();
       
        this.position = position;
       
        Properties BOARD_PROPERTIES = new Properties();
        Path propFile = Main.DIRECTORY.resolve("config").resolve("board.properties");
        try (FileInputStream is = new FileInputStream(propFile.toFile())) {
            BOARD_PROPERTIES.load(is);
        } catch (Exception e) {
            Main.LOG.log(Level.SEVERE, "Cannot load board properties", e);
        }

        pieceset = new CPieceSet(BOARD_PROPERTIES.getProperty("PieceSet"));
        darkColor = Color.decode(BOARD_PROPERTIES.getProperty("DarkColor"));
        lightColor = Color.decode(BOARD_PROPERTIES.getProperty("LightColor"));
        arrowColor = Color.decode(BOARD_PROPERTIES.getProperty("ArrowColor"));
        selectedColor = Color.decode(BOARD_PROPERTIES.getProperty("SelectedColor"));
        selectedColor = new Color(selectedColor.getRed(), selectedColor.getGreen(),
                selectedColor.getBlue(), 128);
        int width = Integer.parseInt(BOARD_PROPERTIES.getProperty("Width"));
        int height = Integer.parseInt(BOARD_PROPERTIES.getProperty("Height"));
        this.setPreferredSize(new Dimension(width, height));
       
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }
   
    public CBoard() {
        this(new CPosition());
    }
   
    @Override
    public void paintComponent(Graphics g) {
        int s = this.getHeight();
        if (this.getWidth() < s) {
            s = this.getWidth();
        }
        int size = s / 8;
        drawSquares((Graphics2D)g, size);
        drawSelectedSquares((Graphics2D)g, size);
        drawCoordinates((Graphics2D)g, size);
        drawPieces((Graphics2D)g, size);
        drawArrows((Graphics2D)g, size);
    }
   
    private void drawSquares(Graphics2D g, int size) {
        int x, y;
        ESide color;
        for (ESquare square : ESquare.values()) {
            color = square.getColor();
            x = getX(square, size);
            y = getY(square, size);
            if (color == ESide.WHITE) {
                g.setColor(lightColor);
            } else {
                g.setColor(darkColor);
            }
            g.fillRect(x, y, size, size);
        }
    }
   
    private void drawSelectedSquares(Graphics2D g, int size) {
        g.setColor(selectedColor);
        int x, y;
        for (ESquare square : selectedSquares) {
            x = getX(square, size);
            y = getY(square, size);
            g.fillRect(x, y, size, size);
        }
    }
   
    private void drawPieces(Graphics2D g, int size) {
        EPiece piece;
        int x, y;
        for (ESquare square : position.getPosition().keySet()) {
            if (blindfoldSquares.contains(square)) {
                continue;
            }
            piece = position.getPosition().get(square);
            x = getX(square, size);
            y = getY(square, size);
            if (dragging == true && square == draggingSquare) {
                x = mouseX - (size / 2);
                y = mouseY - (size / 2);
            }
            if (animating == true && square == animateFrom) {
                double now = (double)(System.currentTimeMillis() - animateStart);
                double total = (double)(animateEnd - animateStart);
                double fraction = now / total;
                int x1 = x;
                int y1 = y;
                int x2 = getX(animateTo, size);
                int y2 = getY(animateTo, size);
                x = x1 + (int)(fraction * (double)(x2 - x1));
                y = y1 + (int)(fraction * (double)(y2 - y1));
            }
            g.drawImage(pieceset.getImage(piece), x, y, size, size, this);
        }
    }
   
    private void drawCoordinates(Graphics2D g, int size) {
        int height = g.getFontMetrics().getHeight();
        int width = g.getFontMetrics().stringWidth("8");
        String[] ranks, files;
        if (perspective == ESide.BLACK) {
            files = new String[]{"h", "g", "f", "e", "d", "c", "b", "a"};
            ranks = new String[]{"1", "2", "3", "4", "5", "6", "7", "8"};
        } else {
            files = new String[]{"a", "b", "c", "d", "e", "f", "g", "h"};
            ranks = new String[]{"8", "7", "6", "5", "4", "3", "2", "1"};
        }
        g.setColor(Color.BLACK);
        for (int i = 0; i < 8; i++) {
            g.drawString(ranks[i], 0, (i * size) + height);
        }
        for (int i = 0; i < 8; i++) {
            g.drawString(files[i], i * size, (8 * size) - g.getFontMetrics().getDescent());
        }
    }
   
    private void drawArrows(Graphics2D g, int size) {
        int middle = size / 2;
        int x1, y1, x2, y2;
        g.setColor(arrowColor);
       
        for (CArrow arrow : arrows) {
            x1 = getX(arrow.getFrom(), size) + middle;
            y1 = getY(arrow.getFrom(), size) + middle;
            x2 = getX(arrow.getTo(), size) + middle;
            y2 = getY(arrow.getTo(), size) + middle;
            g.drawLine(x1, y1, x2, y2);
            g.fillOval(x2, y2, middle / 3, middle / 3);
        }
    }
   
    private int getX(ESquare square, int size) {
        int file = square.getFile();
        if (perspective == ESide.BLACK) {
            file = 7 - file;
        }
        return file * size;
    }
   
    private int getY(ESquare square, int size) {
        int rank = square.getRank();
        if (perspective == ESide.WHITE) {
            rank = 7 - rank;
        }
        return rank * size;
    }
   
    private ESquare getSquare(int x, int y) {
        int s = this.getHeight();
        if (this.getWidth() < s) {
            s = this.getWidth();
        }
        int size = s / 8;
        int rank = 7 - (y / size);
        int file = x / size;
        if (perspective == ESide.BLACK) {
            rank = 7 - rank;
            file = 7 - file;
        }
        return ESquare.get(rank, file);
    }
   
    public void addBoardListener(IBoardListener listener) {
        listeners.add(listener);
    }
   
    public void removeBoardListener(IBoardListener listener) {
        listeners.remove(listener);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // nothing, will do by press-release
    }

    @Override
    public void mousePressed(MouseEvent e) {
        dragging = true;
        mouseX = e.getX();
        mouseY = e.getY();
        draggingSquare = getSquare(mouseX, mouseY);
        repaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        dragging = false;
        mouseX = e.getX();
        mouseY = e.getY();
        ESquare sq = getSquare(mouseX, mouseY);
        if (draggingSquare == sq) {
            for (IBoardListener listener : listeners) {
                listener.boardClicked(sq, e.getButton());
            }
            Main.LOG.log(Level.INFO, "Board clicked: {0}", sq.name());
        } else {
            for (IBoardListener listener : listeners) {
                listener.boardDragged(draggingSquare, sq, e.getButton());
            }
            Main.LOG.log(Level.INFO, "Board dragged: {0} to {1}", new Object[]{draggingSquare.name(), sq.name()});
        }
        repaint();
    }

    @Override
    public void mouseEntered(MouseEvent e) {
       
    }

    @Override
    public void mouseExited(MouseEvent e) {
        dragging = false;
        draggingSquare = null;
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
        if (dragging) {
            repaint();
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
        if (dragging) {
            repaint();
        }
    }
   
    public void animate(ESquare from, ESquare to, int milliseconds) {
        animating = true;
        animateFrom = from;
        animateTo = to;
        animateStart = System.currentTimeMillis();
        animateEnd = animateStart + milliseconds;
       
        while (System.currentTimeMillis() < animateEnd) {
            repaint();
            Thread.yield();
        }
       
        animating = false;
    }

    public Set<ESquare> getSelectedSquares() {
        return selectedSquares;
    }

    public Set<CArrow> getArrows() {
        return arrows;
    }

    public Set<ESquare> getBlindfoldSquares() {
        return blindfoldSquares;
    }

    public CPieceSet getPieceset() {
        return pieceset;
    }

    public void setPieceset(CPieceSet pieceset) {
        this.pieceset = pieceset;
    }

    public Color getDarkColor() {
        return darkColor;
    }

    public void setDarkColor(Color darkColor) {
        this.darkColor = darkColor;
    }

    public Color getLightColor() {
        return lightColor;
    }

    public void setLightColor(Color lightColor) {
        this.lightColor = lightColor;
    }

    public Color getArrowColor() {
        return arrowColor;
    }

    public void setArrowColor(Color arrowColor) {
        this.arrowColor = arrowColor;
    }

    public Color getSelectedColor() {
        return selectedColor;
    }

    public void setSelectedColor(Color selectedColor) {
        this.selectedColor = selectedColor;
    }

    public ESide getPerspective() {
        return perspective;
    }

    public void setPerspective(ESide perspective) {
        this.perspective = perspective;
    }

    public CPosition getPosition() {
        return position;
    }

    public void setPosition(CPosition position) {
        this.position = position;
    }
   
   
}
TOP

Related Classes of chesstrainer.ui.CBoard

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.