package dev.kske.chess.ui; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import dev.kske.chess.board.Move; import dev.kske.chess.board.Position; /** * Project: Chess
* File: OverlayComponent.java
* Created: 08.07.2019
* Author: Kai S. K. Engelbart */ public class OverlayComponent extends JComponent { private static final long serialVersionUID = -7326936060890082183L; private final BoardPane boardPane; private List dots; private Move arrow; public OverlayComponent(BoardPane boardPane) { this.boardPane = boardPane; setSize(boardPane.getPreferredSize()); dots = new ArrayList<>(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); final int tileSize = getTileSize(); // Draw possible moves if a piece was selected if (!dots.isEmpty()) { g.setColor(Color.green); int radius = tileSize / 4; for (Position dot : dots) g.fillOval(dot.x * tileSize + tileSize / 2 - radius / 2, dot.y * tileSize + tileSize / 2 - radius / 2, radius, radius); } if (arrow != null) { g.setColor(new Color(255, 0, 0, 127)); Point pos = new Point(arrow.pos.x * tileSize + tileSize / 2, arrow.pos.y * tileSize + tileSize / 2); Point dest = new Point(arrow.dest.x * tileSize + tileSize / 2, arrow.dest.y * tileSize + tileSize / 2); ((Graphics2D) g).fill(createArrowShape(pos, dest)); } } private Shape createArrowShape(Point pos, Point dest) { Polygon arrowPolygon = new Polygon(); arrowPolygon.addPoint(-6, 1); arrowPolygon.addPoint(3, 1); arrowPolygon.addPoint(3, 3); arrowPolygon.addPoint(6, 0); arrowPolygon.addPoint(3, -3); arrowPolygon.addPoint(3, -1); arrowPolygon.addPoint(-6, -1); Point midPoint = midpoint(pos, dest); double rotate = Math.atan2(dest.y - pos.y, dest.x - pos.x); double ptDistance = pos.distance(dest); double scale = ptDistance / 12.0; // 12 because it's the length of the arrow // polygon. AffineTransform transform = new AffineTransform(); transform.translate(midPoint.x, midPoint.y); transform.rotate(rotate); transform.scale(scale, 5); return transform.createTransformedShape(arrowPolygon); } private Point midpoint(Point p1, Point p2) { return new Point((int) ((p1.x + p2.x) / 2.0), (int) ((p1.y + p2.y) / 2.0)); } public void displayDots(List dots) { this.dots.clear(); this.dots.addAll(dots); repaint(); } public void clearDots() { dots.clear(); repaint(); } public void displayArrow(Move arrow) { this.arrow = arrow; repaint(); } public void clearArrow() { arrow = null; repaint(); } public int getTileSize() { return boardPane.getTileSize(); } }