1 package cz.xelfi.quoridor.visidor;
3 import cz.xelfi.quoridor.Board;
4 import cz.xelfi.quoridor.Fence;
5 import cz.xelfi.quoridor.Fence.Orientation;
6 import cz.xelfi.quoridor.IllegalPositionException;
7 import cz.xelfi.quoridor.Move;
8 import cz.xelfi.quoridor.Player;
10 import java.awt.Graphics2D;
11 import java.awt.Point;
12 import java.awt.Rectangle;
13 import javax.swing.JFrame;
14 import javax.swing.JPanel;
15 import org.netbeans.api.visual.action.MoveProvider;
16 import org.netbeans.api.visual.border.BorderFactory;
17 import org.netbeans.api.visual.widget.ImageWidget;
18 import org.netbeans.api.visual.widget.LayerWidget;
19 import org.netbeans.api.visual.widget.Scene;
20 import org.netbeans.api.visual.widget.Widget;
21 import org.openide.util.Exceptions;
25 * @author Jaroslav Tulach <jtulach@netbeans.org>
27 final class Viewer extends JPanel {
29 private final Scene scene;
35 private Viewer(Board b) {
37 this.scene = new Scene();
38 add(scene.createView());
44 * @param args the command line arguments
46 public static void main(String[] args) throws IllegalPositionException {
47 Board b = Board.empty();
48 for (int i = 1; i <= 8; i++) {
49 b = b.apply(Move.fence('A', i, Orientation.values()[i % 2]));
51 for (int i = 1; i <= 8; i++) {
52 b = b.apply(Move.fence('H', i, Orientation.values()[(i + 1) % 2]));
55 JFrame f = new JFrame();
56 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
62 private void view(Scene scene, Board b) {
63 scene.removeChildren();
67 static void drawBoard(Scene scene, Board b) {
68 // Scene layerBoard = scene;
69 scene.setPreferredLocation(new Point(0, 0));
70 final LayerWidget layerLines = new LayerWidget(scene);
71 scene.addChild(layerLines);
72 final LayerWidget layerBoard = new LayerWidget(scene);
73 layerLines.addChild(layerBoard);
78 for (int i = 0; i < 9; i++) {
79 for (int j = 0; j < 9; j++) {
80 Widget w = new FieldWidget(scene);
81 w.setPreferredBounds(new Rectangle(i * WDTH, j * HGHT, WDTH, HGHT));
82 layerBoard.addChild(w);
87 ImageWidget horizontalWall = new ImageWidget(scene);
88 horizontalWall.setPreferredBounds(new Rectangle(550, 300, 90, 10));
89 horizontalWall.setBackground(Color.BLACK);
90 horizontalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(true)));
91 horizontalWall.setBorder(BorderFactory.createLineBorder());
92 horizontalWall.setOpaque(true);
93 layerBoard.addChild(horizontalWall);
95 ImageWidget verticalWall = new ImageWidget(scene);
96 verticalWall.setPreferredBounds(new Rectangle(600, 150, 10, 90));
97 verticalWall.setBackground(Color.BLACK);
98 verticalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(false)));
99 verticalWall.setBorder(BorderFactory.createLineBorder());
100 verticalWall.setOpaque(true);
101 layerBoard.addChild(verticalWall);
103 for (Fence f : b.getFences()) {
104 Rectangle r = fenceRectangle(f.getColumn(), f.getRow(), f.getOrientation());
105 ImageWidget fenceWall = new ImageWidget(scene);
106 fenceWall.setPreferredBounds(r);
107 fenceWall.setBackground(Color.BLACK);
108 fenceWall.setBorder(BorderFactory.createLineBorder());
109 fenceWall.setOpaque(true);
110 layerBoard.addChild(fenceWall);
114 Color[] colors = { Color.WHITE, Color.BLACK, Color.ORANGE, Color.MAGENTA };
115 for (Player p : b.getPlayers()) {
116 PlayerWidget pw = new PlayerWidget(scene, colors[cnt]);
117 pw.setPreferredBounds(new Rectangle(p.getColumn() * WDTH, p.getRow() * HGHT, WDTH, HGHT));
118 layerBoard.addChild(pw);
124 private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) {
127 case HORIZONTAL: w = 45; h = 5; break;
128 case VERTICAL: w = 5; h = 45; break;
129 default: throw new IllegalStateException();
132 return new Rectangle(
133 (column - 'A' + 1) * 50 - w, row * 50 - h, 2 * w, 2 * h
137 private class MoveControl implements MoveProvider {
138 final boolean horizontal;
142 private MoveControl(boolean horizontal) {
143 this.horizontal = horizontal;
145 public void movementStarted(Widget widget) {
146 System.err.println("started: " + widget.getBounds());
149 public void movementFinished(Widget widget) {
151 final Rectangle bounds = widget.getBounds();
152 final Move m = createMoveForDrop( bounds);
153 System.err.println("finish: " + m);
154 board = board.apply(m);
155 } catch (IllegalPositionException ex) {
156 Exceptions.printStackTrace(ex);
162 public Point getOriginalLocation(Widget widget) {
163 final Rectangle b = widget.getBounds();
164 orig = new Point(b.x, b.y);
166 System.err.println(" where: " + createMoveForDrop(b));
167 } catch (IllegalPositionException ex) {
168 Exceptions.printStackTrace(ex);
173 public void setNewLocation(Widget widget, Point location) {
174 final Rectangle b = new Rectangle(
175 round(location.x, true) + (horizontal ? 5 : 0),
176 round(location.y, false) + (horizontal ? 0 : 5),
177 horizontal ? 90 : 10,
180 widget.setPreferredBounds(b);
182 System.err.println("move: " + createMoveForDrop(b));
183 } catch (IllegalPositionException ex) {
184 System.err.println("no move");
188 Move createMoveForDrop(final Rectangle bounds) throws IllegalPositionException {
189 int column = bounds.x / 50;
190 int row = bounds.y / 50;
191 Orientation o = bounds.width > bounds.height ? Orientation.HORIZONTAL : Orientation.VERTICAL;
193 case HORIZONTAL: row--; break;
194 case VERTICAL: column--; break;
195 default: assert false;
209 Move m = Move.fence((char) ('A' + column), 1 + row, o);
213 int round(int p, boolean cmpHori) {
214 // p = horizontal ? orig.x + p: orig.y + p;
215 int onboard = p / 50;
222 int real = 25 + onboard * 50;
223 if (horizontal != cmpHori) {
231 private static final class PlayerWidget extends Widget {
232 private final Color color;
234 public PlayerWidget(Scene s, Color color) {
240 protected Rectangle calculateClientArea() {
245 protected void paintWidget() {
246 Graphics2D g = getGraphics();
247 Rectangle b = getBounds();
249 g.fillOval(b.x + 8, b.y + 8, b.width - 16, b.height - 16);
252 private static final class FieldWidget extends Widget {
253 public FieldWidget(Scene s) {
258 protected Rectangle calculateClientArea() {
263 protected void paintWidget() {
264 Graphics2D g = getGraphics();
265 Rectangle b = getBounds();
266 g.setColor(Color.lightGray);
267 g.fillRect(b.x + 5, b.y + 5, b.width - 10, b.height - 10);