visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
author Jaroslav Tulach <jtulach@netbeans.org>
Wed, 16 Sep 2009 22:28:11 +0200
branchdisplay-image
changeset 91 786df32c496b
parent 33 6a6d1dbea99e
permissions -rw-r--r--
First attempt to show the board as image
     1 package cz.xelfi.quoridor.visidor;
     2 
     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;
     9 import java.awt.Color;
    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;
    22 
    23 /**
    24  *
    25  * @author Jaroslav Tulach <jtulach@netbeans.org>
    26  */
    27 final class Viewer extends JPanel {
    28     private Board board;
    29     private final Scene scene;
    30 
    31     public Viewer() {
    32         this(Board.empty());
    33     }
    34 
    35     private Viewer(Board b) {
    36         this.board = b;
    37         this.scene = new Scene();
    38         add(scene.createView());
    39         view(scene, board);
    40     }
    41 
    42 
    43     /**
    44      * @param args the command line arguments
    45      */
    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]));
    50         }
    51         for (int i = 1; i <= 8; i++) {
    52             b = b.apply(Move.fence('H', i, Orientation.values()[(i + 1) % 2]));
    53         }
    54 
    55         JFrame f = new JFrame();
    56         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    57         f.add(new Viewer(b));
    58         f.pack();
    59         f.setVisible(true);
    60     }
    61 
    62     private void view(Scene scene, Board b) {
    63         scene.removeChildren();
    64         drawBoard(scene, b);
    65     }
    66 
    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);
    74         final int WDTH = 50;
    75         final int HGHT = 50;
    76 
    77         
    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);
    83             }
    84         }
    85 
    86 /*
    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);
    94 
    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);
   102 */
   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);
   111         }
   112 
   113         int cnt = 0;
   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);
   119 
   120             cnt++;
   121         }
   122     }
   123 
   124     private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) {
   125         int w, h;
   126         switch (o) {
   127             case HORIZONTAL: w = 45; h = 5; break;
   128             case VERTICAL: w = 5; h = 45; break;
   129             default: throw new IllegalStateException();
   130         }
   131 
   132         return new Rectangle(
   133             (column - 'A' + 1) * 50 - w, row * 50 - h, 2 * w, 2 * h
   134         );
   135     }
   136 
   137     private class MoveControl implements MoveProvider {
   138         final boolean horizontal;
   139 
   140         Point orig;
   141 
   142         private MoveControl(boolean horizontal) {
   143             this.horizontal = horizontal;
   144         }
   145         public void movementStarted(Widget widget) {
   146             System.err.println("started: " + widget.getBounds());
   147         }
   148 
   149         public void movementFinished(Widget widget) {
   150             try {
   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);
   157             }
   158 
   159             view(scene, board);
   160         }
   161 
   162         public Point getOriginalLocation(Widget widget) {
   163             final Rectangle b = widget.getBounds();
   164             orig = new Point(b.x, b.y);
   165             try {
   166                 System.err.println("  where: " + createMoveForDrop(b));
   167             } catch (IllegalPositionException ex) {
   168                 Exceptions.printStackTrace(ex);
   169             }
   170             return orig;
   171         }
   172 
   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,
   178                 horizontal ? 10 : 90
   179             );
   180             widget.setPreferredBounds(b);
   181             try {
   182                 System.err.println("move: " + createMoveForDrop(b));
   183             } catch (IllegalPositionException ex) {
   184                 System.err.println("no move");
   185             }
   186         }
   187 
   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;
   192             switch (o) {
   193                 case HORIZONTAL: row--; break;
   194                 case VERTICAL: column--; break;
   195                 default: assert false;
   196             }
   197             if (column < 0) {
   198                 column = 0;
   199             }
   200             if (column >= 9) {
   201                 column = 8;
   202             }
   203             if (row < 0) {
   204                 row = 0;
   205             }
   206             if (row > 8) {
   207                 row = 8;
   208             }
   209             Move m = Move.fence((char) ('A' + column), 1 + row, o);
   210             return m;
   211         }
   212 
   213         int round(int p, boolean cmpHori) {
   214     //        p = horizontal ? orig.x + p: orig.y + p;
   215             int onboard = p / 50;
   216             if (onboard < 0) {
   217                 onboard = 0;
   218             }
   219             if (onboard >= 9) {
   220                 return p;
   221             }
   222             int real = 25 + onboard * 50;
   223             if (horizontal != cmpHori) {
   224                 return real - 5;
   225             } else {
   226                 return real;
   227             }
   228         }
   229     }
   230 
   231     private static final class PlayerWidget extends Widget {
   232         private final Color color;
   233 
   234         public PlayerWidget(Scene s, Color color) {
   235             super(s);
   236             this.color = color;
   237         }
   238 
   239         @Override
   240         protected Rectangle calculateClientArea() {
   241             return getBounds();
   242         }
   243 
   244         @Override
   245         protected void paintWidget() {
   246             Graphics2D g = getGraphics();
   247             Rectangle b = getBounds();
   248             g.setColor(color);
   249             g.fillOval(b.x + 8, b.y + 8, b.width - 16, b.height - 16);
   250         }
   251     }
   252     private static final class FieldWidget extends Widget {
   253         public FieldWidget(Scene s) {
   254             super(s);
   255         }
   256 
   257         @Override
   258         protected Rectangle calculateClientArea() {
   259             return getBounds();
   260         }
   261 
   262         @Override
   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);
   268         }
   269     }
   270 }