package jrummikub.view.impl; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; import java.util.Collections; import java.util.Map; import javax.swing.JPanel; import jrummikub.model.Position; import jrummikub.model.Stone; import jrummikub.util.Event1; import jrummikub.util.Event2; import jrummikub.view.IClickable; import jrummikub.view.IStonePanel; /** * Base class for panels that draw stones */ @SuppressWarnings("serial") abstract class AbstractStonePanel extends JPanel implements IStonePanel, IClickable { private StonePainter stonePainter; private Event1 clickEvent = new Event1(); private Event2 stoneClickEvent = new Event2(); private Event2 rangeClickEvent = new Event2(); private Event2 setClickEvent = new Event2(); private Map stones = Collections.emptyMap(); /** * @return the stone painter */ protected StonePainter getStonePainter() { return stonePainter; } /** * Create a new StonePanel with default scale factor */ public AbstractStonePanel() { this(1); } /** * Create a new StonePanel with a given scale factor * * @param scale * the grid scale */ public AbstractStonePanel(float scale) { super(true); // Set double buffered stonePainter = new StonePainter(scale); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { Insets insets = getInsets(); Position pos = stonePainter.calculatePosition(e.getX() - insets.left, e.getY() - insets.top); Stone stone = getStoneAt(pos); if (stone == null) { clickEvent.emit(pos); return; } Event2 event = stoneClickEvent; if (e.isShiftDown()) event = rangeClickEvent; else if (e.getClickCount() >= 2) event = setClickEvent; event.emit(stone, e.isControlDown()); } }); } private Stone getStoneAt(Position pos) { for (Map.Entry entry : stones.entrySet()) { Stone stone = entry.getKey(); Position p = entry.getValue(); Rectangle2D rect = new Rectangle2D.Float(p.getX(), p.getY(), stone.getWidth(), stone.getHeight()); if (rect.contains(pos.getX(), pos.getY())) return stone; } return null; } /** * Sets the list of stones that can be clicked on * * @param stones * the stones and positions */ protected void setStones(Map stones) { this.stones = stones; } /** * Returns the list of stones and positions currently set * * @return the stones */ protected Map getStones() { return stones; } @Override public Event1 getClickEvent() { return clickEvent; } @Override public Event2 getStoneClickEvent() { return stoneClickEvent; } @Override public Event2 getRangeClickEvent() { return rangeClickEvent; } @Override public Event2 getSetClickEvent() { return setClickEvent; } }