jtulach@25: package cz.xelfi.quoridor.visidor; jtulach@18: jtulach@23: import cz.xelfi.quoridor.Board; jtulach@23: import cz.xelfi.quoridor.Fence; jtulach@23: import cz.xelfi.quoridor.Fence.Orientation; jtulach@23: import cz.xelfi.quoridor.IllegalPositionException; jtulach@23: import cz.xelfi.quoridor.Move; jtulach@29: import cz.xelfi.quoridor.Player; jtulach@18: import java.awt.Color; jtulach@29: import java.awt.Graphics2D; jtulach@18: import java.awt.Point; jtulach@18: import java.awt.Rectangle; jtulach@18: import javax.swing.JFrame; jtulach@29: import javax.swing.JPanel; jtulach@18: import org.netbeans.api.visual.action.MoveProvider; jtulach@18: import org.netbeans.api.visual.border.BorderFactory; jtulach@18: import org.netbeans.api.visual.widget.ImageWidget; jtulach@18: import org.netbeans.api.visual.widget.LayerWidget; jtulach@18: import org.netbeans.api.visual.widget.Scene; jtulach@18: import org.netbeans.api.visual.widget.Widget; jtulach@29: import org.openide.util.Exceptions; jtulach@18: jtulach@18: /** jtulach@18: * jtulach@18: * @author Jaroslav Tulach jtulach@18: */ jtulach@29: final class Viewer extends JPanel { jtulach@29: private Board board; jtulach@29: private final Scene scene; jtulach@29: jtulach@29: public Viewer() { jtulach@29: this(Board.empty()); jtulach@29: } jtulach@29: jtulach@29: private Viewer(Board b) { jtulach@29: this.board = b; jtulach@29: this.scene = new Scene(); jtulach@29: add(scene.createView()); jtulach@29: view(scene, board); jtulach@29: } jtulach@29: jtulach@18: jtulach@18: /** jtulach@18: * @param args the command line arguments jtulach@18: */ jtulach@23: public static void main(String[] args) throws IllegalPositionException { jtulach@23: Board b = Board.empty(); jtulach@23: for (int i = 1; i <= 8; i++) { jtulach@23: b = b.apply(Move.fence('A', i, Orientation.values()[i % 2])); jtulach@23: } jtulach@23: for (int i = 1; i <= 8; i++) { jtulach@23: b = b.apply(Move.fence('H', i, Orientation.values()[(i + 1) % 2])); jtulach@23: } jtulach@29: jtulach@29: JFrame f = new JFrame(); jtulach@29: f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jtulach@29: f.add(new Viewer(b)); jtulach@29: f.pack(); jtulach@29: f.setVisible(true); jtulach@23: } jtulach@23: jtulach@29: private void view(Scene scene, Board b) { jtulach@29: scene.removeChildren(); jtulach@91: drawBoard(scene, b); jtulach@91: } jtulach@91: jtulach@91: static void drawBoard(Scene scene, Board b) { jtulach@18: // Scene layerBoard = scene; jtulach@91: scene.setPreferredLocation(new Point(0, 0)); jtulach@18: final LayerWidget layerLines = new LayerWidget(scene); jtulach@18: scene.addChild(layerLines); jtulach@18: final LayerWidget layerBoard = new LayerWidget(scene); jtulach@18: layerLines.addChild(layerBoard); jtulach@29: final int WDTH = 50; jtulach@29: final int HGHT = 50; jtulach@91: jtulach@91: jtulach@91: for (int i = 0; i < 9; i++) { jtulach@91: for (int j = 0; j < 9; j++) { jtulach@91: Widget w = new FieldWidget(scene); jtulach@29: w.setPreferredBounds(new Rectangle(i * WDTH, j * HGHT, WDTH, HGHT)); jtulach@18: layerBoard.addChild(w); jtulach@18: } jtulach@18: } jtulach@18: jtulach@91: /* jtulach@18: ImageWidget horizontalWall = new ImageWidget(scene); jtulach@19: horizontalWall.setPreferredBounds(new Rectangle(550, 300, 90, 10)); jtulach@18: horizontalWall.setBackground(Color.BLACK); jtulach@29: horizontalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(true))); jtulach@18: horizontalWall.setBorder(BorderFactory.createLineBorder()); jtulach@24: horizontalWall.setOpaque(true); jtulach@18: layerBoard.addChild(horizontalWall); jtulach@18: jtulach@18: ImageWidget verticalWall = new ImageWidget(scene); jtulach@19: verticalWall.setPreferredBounds(new Rectangle(600, 150, 10, 90)); jtulach@18: verticalWall.setBackground(Color.BLACK); jtulach@29: verticalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(false))); jtulach@18: verticalWall.setBorder(BorderFactory.createLineBorder()); jtulach@24: verticalWall.setOpaque(true); jtulach@18: layerBoard.addChild(verticalWall); jtulach@91: */ jtulach@23: for (Fence f : b.getFences()) { jtulach@23: Rectangle r = fenceRectangle(f.getColumn(), f.getRow(), f.getOrientation()); jtulach@23: ImageWidget fenceWall = new ImageWidget(scene); jtulach@23: fenceWall.setPreferredBounds(r); jtulach@23: fenceWall.setBackground(Color.BLACK); jtulach@23: fenceWall.setBorder(BorderFactory.createLineBorder()); jtulach@24: fenceWall.setOpaque(true); jtulach@23: layerBoard.addChild(fenceWall); jtulach@23: } jtulach@23: jtulach@29: int cnt = 0; jtulach@91: Color[] colors = { Color.WHITE, Color.BLACK, Color.ORANGE, Color.MAGENTA }; jtulach@29: for (Player p : b.getPlayers()) { jtulach@91: PlayerWidget pw = new PlayerWidget(scene, colors[cnt]); jtulach@91: pw.setPreferredBounds(new Rectangle(p.getColumn() * WDTH, p.getRow() * HGHT, WDTH, HGHT)); jtulach@29: layerBoard.addChild(pw); jtulach@29: jtulach@29: cnt++; jtulach@29: } jtulach@18: } jtulach@18: jtulach@23: private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) { jtulach@23: int w, h; jtulach@23: switch (o) { jtulach@23: case HORIZONTAL: w = 45; h = 5; break; jtulach@23: case VERTICAL: w = 5; h = 45; break; jtulach@23: default: throw new IllegalStateException(); jtulach@23: } jtulach@23: jtulach@23: return new Rectangle( jtulach@91: (column - 'A' + 1) * 50 - w, row * 50 - h, 2 * w, 2 * h jtulach@23: ); jtulach@23: } jtulach@23: jtulach@29: private class MoveControl implements MoveProvider { jtulach@29: final boolean horizontal; jtulach@18: jtulach@29: Point orig; jtulach@18: jtulach@29: private MoveControl(boolean horizontal) { jtulach@29: this.horizontal = horizontal; jtulach@29: } jtulach@29: public void movementStarted(Widget widget) { jtulach@29: System.err.println("started: " + widget.getBounds()); jtulach@29: } jtulach@29: jtulach@29: public void movementFinished(Widget widget) { jtulach@29: try { jtulach@32: final Rectangle bounds = widget.getBounds(); jtulach@32: final Move m = createMoveForDrop( bounds); jtulach@32: System.err.println("finish: " + m); jtulach@32: board = board.apply(m); jtulach@29: } catch (IllegalPositionException ex) { jtulach@29: Exceptions.printStackTrace(ex); jtulach@29: } jtulach@29: jtulach@29: view(scene, board); jtulach@29: } jtulach@29: jtulach@29: public Point getOriginalLocation(Widget widget) { jtulach@32: final Rectangle b = widget.getBounds(); jtulach@32: orig = new Point(b.x, b.y); jtulach@32: try { jtulach@32: System.err.println(" where: " + createMoveForDrop(b)); jtulach@32: } catch (IllegalPositionException ex) { jtulach@32: Exceptions.printStackTrace(ex); jtulach@32: } jtulach@29: return orig; jtulach@29: } jtulach@29: jtulach@29: public void setNewLocation(Widget widget, Point location) { jtulach@32: final Rectangle b = new Rectangle( jtulach@29: round(location.x, true) + (horizontal ? 5 : 0), jtulach@29: round(location.y, false) + (horizontal ? 0 : 5), jtulach@29: horizontal ? 90 : 10, jtulach@32: horizontal ? 10 : 90 jtulach@29: ); jtulach@32: widget.setPreferredBounds(b); jtulach@32: try { jtulach@32: System.err.println("move: " + createMoveForDrop(b)); jtulach@32: } catch (IllegalPositionException ex) { jtulach@32: System.err.println("no move"); jtulach@32: } jtulach@32: } jtulach@32: jtulach@32: Move createMoveForDrop(final Rectangle bounds) throws IllegalPositionException { jtulach@32: int column = bounds.x / 50; jtulach@32: int row = bounds.y / 50; jtulach@32: Orientation o = bounds.width > bounds.height ? Orientation.HORIZONTAL : Orientation.VERTICAL; jtulach@32: switch (o) { jtulach@32: case HORIZONTAL: row--; break; jtulach@32: case VERTICAL: column--; break; jtulach@32: default: assert false; jtulach@32: } jtulach@32: if (column < 0) { jtulach@32: column = 0; jtulach@32: } jtulach@32: if (column >= 9) { jtulach@32: column = 8; jtulach@32: } jtulach@32: if (row < 0) { jtulach@32: row = 0; jtulach@32: } jtulach@32: if (row > 8) { jtulach@32: row = 8; jtulach@32: } jtulach@32: Move m = Move.fence((char) ('A' + column), 1 + row, o); jtulach@32: return m; jtulach@29: } jtulach@29: jtulach@29: int round(int p, boolean cmpHori) { jtulach@29: // p = horizontal ? orig.x + p: orig.y + p; jtulach@29: int onboard = p / 50; jtulach@29: if (onboard < 0) { jtulach@29: onboard = 0; jtulach@29: } jtulach@29: if (onboard >= 9) { jtulach@29: return p; jtulach@29: } jtulach@29: int real = 25 + onboard * 50; jtulach@29: if (horizontal != cmpHori) { jtulach@29: return real - 5; jtulach@29: } else { jtulach@29: return real; jtulach@29: } jtulach@29: } jtulach@18: } jtulach@18: jtulach@29: private static final class PlayerWidget extends Widget { jtulach@91: private final Color color; jtulach@91: jtulach@91: public PlayerWidget(Scene s, Color color) { jtulach@91: super(s); jtulach@91: this.color = color; jtulach@91: } jtulach@91: jtulach@91: @Override jtulach@91: protected Rectangle calculateClientArea() { jtulach@91: return getBounds(); jtulach@91: } jtulach@91: jtulach@91: @Override jtulach@91: protected void paintWidget() { jtulach@91: Graphics2D g = getGraphics(); jtulach@91: Rectangle b = getBounds(); jtulach@91: g.setColor(color); jtulach@91: g.fillOval(b.x + 8, b.y + 8, b.width - 16, b.height - 16); jtulach@91: } jtulach@91: } jtulach@91: private static final class FieldWidget extends Widget { jtulach@91: public FieldWidget(Scene s) { jtulach@29: super(s); jtulach@29: } jtulach@18: jtulach@29: @Override jtulach@29: protected Rectangle calculateClientArea() { jtulach@33: return getBounds(); jtulach@29: } jtulach@18: jtulach@29: @Override jtulach@29: protected void paintWidget() { jtulach@29: Graphics2D g = getGraphics(); jtulach@33: Rectangle b = getBounds(); jtulach@91: g.setColor(Color.lightGray); jtulach@91: g.fillRect(b.x + 5, b.y + 5, b.width - 10, b.height - 10); jtulach@18: } jtulach@18: } jtulach@18: }