visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 06 Jun 2009 15:13:04 +0200
changeset 33 6a6d1dbea99e
parent 32 b6b0a99745b4
child 91 786df32c496b
child 178 4b78d4f028b3
permissions -rw-r--r--
Drawing players to the right position
     1 /*
     2  * To change this template, choose Tools | Templates
     3  * and open the template in the editor.
     4  */
     5 
     6 package cz.xelfi.quoridor.visidor;
     7 
     8 import cz.xelfi.quoridor.Board;
     9 import cz.xelfi.quoridor.Fence;
    10 import cz.xelfi.quoridor.Fence.Orientation;
    11 import cz.xelfi.quoridor.IllegalPositionException;
    12 import cz.xelfi.quoridor.Move;
    13 import cz.xelfi.quoridor.Player;
    14 import java.awt.Color;
    15 import java.awt.Graphics2D;
    16 import java.awt.Point;
    17 import java.awt.Rectangle;
    18 import javax.swing.JFrame;
    19 import javax.swing.JPanel;
    20 import org.netbeans.api.visual.action.ActionFactory;
    21 import org.netbeans.api.visual.action.MoveProvider;
    22 import org.netbeans.api.visual.anchor.AnchorFactory;
    23 import org.netbeans.api.visual.border.BorderFactory;
    24 import org.netbeans.api.visual.widget.ConnectionWidget;
    25 import org.netbeans.api.visual.widget.ImageWidget;
    26 import org.netbeans.api.visual.widget.LabelWidget;
    27 import org.netbeans.api.visual.widget.LayerWidget;
    28 import org.netbeans.api.visual.widget.Scene;
    29 import org.netbeans.api.visual.widget.Widget;
    30 import org.openide.util.Exceptions;
    31 
    32 /**
    33  *
    34  * @author Jaroslav Tulach <jtulach@netbeans.org>
    35  */
    36 final class Viewer extends JPanel {
    37     private Board board;
    38     private final Scene scene;
    39 
    40     public Viewer() {
    41         this(Board.empty());
    42     }
    43 
    44     private Viewer(Board b) {
    45         this.board = b;
    46         this.scene = new Scene();
    47         add(scene.createView());
    48         view(scene, board);
    49     }
    50 
    51 
    52     /**
    53      * @param args the command line arguments
    54      */
    55     public static void main(String[] args) throws IllegalPositionException {
    56         Board b = Board.empty();
    57         for (int i = 1; i <= 8; i++) {
    58             b = b.apply(Move.fence('A', i, Orientation.values()[i % 2]));
    59         }
    60         for (int i = 1; i <= 8; i++) {
    61             b = b.apply(Move.fence('H', i, Orientation.values()[(i + 1) % 2]));
    62         }
    63 
    64         JFrame f = new JFrame();
    65         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    66         f.add(new Viewer(b));
    67         f.pack();
    68         f.setVisible(true);
    69     }
    70 
    71     private void view(Scene scene, Board b) {
    72         scene.removeChildren();
    73 //        Scene layerBoard = scene;
    74         final LayerWidget layerLines = new LayerWidget(scene);
    75         scene.addChild(layerLines);
    76         final LayerWidget layerBoard = new LayerWidget(scene);
    77         layerLines.addChild(layerBoard);
    78         final int WDTH = 50;
    79         final int HGHT = 50;
    80 //        conn.setSourceAnchor(ahoj);
    81         Widget[][] fields = new Widget[10][];
    82         for (int i = 0; i < fields.length; i++) {
    83             fields[i] = new Widget[10];
    84             for (int j = 0; j < fields[i].length; j++) {
    85                 LabelWidget w = new LabelWidget(scene);
    86                 w.setPreferredBounds(new Rectangle(i * WDTH, j * HGHT, WDTH, HGHT));
    87                 layerBoard.addChild(w);
    88                 fields[i][j] = w;
    89             }
    90         }
    91         for (int i = 0; i < fields.length; i++) {
    92             for (int j = 0; j < fields[i].length; j++) {
    93                 if (i > 0) {
    94                     ConnectionWidget horiz = new ConnectionWidget(scene);
    95                     horiz.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i - 1][j]));
    96                     horiz.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
    97                     scene.addChild(horiz);
    98                 }
    99                 if (j > 0) {
   100                     ConnectionWidget vert = new ConnectionWidget(scene);
   101                     vert.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i][j - 1]));
   102                     vert.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
   103                     scene.addChild(vert);
   104                 }
   105             }
   106         }
   107 
   108         ImageWidget horizontalWall = new ImageWidget(scene);
   109         horizontalWall.setPreferredBounds(new Rectangle(550, 300, 90, 10));
   110         horizontalWall.setBackground(Color.BLACK);
   111         horizontalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(true)));
   112         horizontalWall.setBorder(BorderFactory.createLineBorder());
   113         horizontalWall.setOpaque(true);
   114         layerBoard.addChild(horizontalWall);
   115 
   116         ImageWidget verticalWall = new ImageWidget(scene);
   117         verticalWall.setPreferredBounds(new Rectangle(600, 150, 10, 90));
   118         verticalWall.setBackground(Color.BLACK);
   119         verticalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(false)));
   120         verticalWall.setBorder(BorderFactory.createLineBorder());
   121         verticalWall.setOpaque(true);
   122         layerBoard.addChild(verticalWall);
   123 
   124         for (Fence f : b.getFences()) {
   125             Rectangle r = fenceRectangle(f.getColumn(), f.getRow(), f.getOrientation());
   126             ImageWidget fenceWall = new ImageWidget(scene);
   127             fenceWall.setPreferredBounds(r);
   128             fenceWall.setBackground(Color.BLACK);
   129             fenceWall.setBorder(BorderFactory.createLineBorder());
   130             fenceWall.setOpaque(true);
   131             layerBoard.addChild(fenceWall);
   132         }
   133 
   134         int cnt = 0;
   135         for (Player p : b.getPlayers()) {
   136             LabelWidget lw = new LabelWidget(scene);
   137             lw.setLabel("" + p.getFences());
   138             if (cnt == 0) {
   139                 lw.setPreferredBounds(new Rectangle(550, 200, 50, 50));
   140             } else {
   141                 lw.setPreferredBounds(new Rectangle(550, 450, 50, 50));
   142             }
   143             layerBoard.addChild(lw);
   144 
   145             PlayerWidget pw = new PlayerWidget(scene);
   146             System.err.println("p: " + p);
   147             pw.setPreferredBounds(new Rectangle(p.getColumn() * 50 + 25, p.getRow() * 50 + 25, 50, 50));
   148             layerBoard.addChild(pw);
   149 
   150             cnt++;
   151         }
   152     }
   153 
   154     private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) {
   155         int w, h;
   156         switch (o) {
   157             case HORIZONTAL: w = 45; h = 5; break;
   158             case VERTICAL: w = 5; h = 45; break;
   159             default: throw new IllegalStateException();
   160         }
   161 
   162         return new Rectangle(
   163             (column - 'A' + 1) * 50 + 25 - w, row * 50 + 25 - h, 2 * w, 2 * h
   164         );
   165     }
   166 
   167     private class MoveControl implements MoveProvider {
   168         final boolean horizontal;
   169 
   170         Point orig;
   171 
   172         private MoveControl(boolean horizontal) {
   173             this.horizontal = horizontal;
   174         }
   175         public void movementStarted(Widget widget) {
   176             System.err.println("started: " + widget.getBounds());
   177         }
   178 
   179         public void movementFinished(Widget widget) {
   180             try {
   181                 final Rectangle bounds = widget.getBounds();
   182                 final Move m = createMoveForDrop( bounds);
   183                 System.err.println("finish: " + m);
   184                 board = board.apply(m);
   185             } catch (IllegalPositionException ex) {
   186                 Exceptions.printStackTrace(ex);
   187             }
   188 
   189             view(scene, board);
   190         }
   191 
   192         public Point getOriginalLocation(Widget widget) {
   193             final Rectangle b = widget.getBounds();
   194             orig = new Point(b.x, b.y);
   195             try {
   196                 System.err.println("  where: " + createMoveForDrop(b));
   197             } catch (IllegalPositionException ex) {
   198                 Exceptions.printStackTrace(ex);
   199             }
   200             return orig;
   201         }
   202 
   203         public void setNewLocation(Widget widget, Point location) {
   204             final Rectangle b = new Rectangle(
   205                 round(location.x, true) + (horizontal ? 5 : 0),
   206                 round(location.y, false) + (horizontal ? 0 : 5),
   207                 horizontal ? 90 : 10,
   208                 horizontal ? 10 : 90
   209             );
   210             widget.setPreferredBounds(b);
   211             try {
   212                 System.err.println("move: " + createMoveForDrop(b));
   213             } catch (IllegalPositionException ex) {
   214                 System.err.println("no move");
   215             }
   216         }
   217 
   218         Move createMoveForDrop(final Rectangle bounds) throws IllegalPositionException {
   219             int column = bounds.x / 50;
   220             int row = bounds.y / 50;
   221             Orientation o = bounds.width > bounds.height ? Orientation.HORIZONTAL : Orientation.VERTICAL;
   222             switch (o) {
   223                 case HORIZONTAL: row--; break;
   224                 case VERTICAL: column--; break;
   225                 default: assert false;
   226             }
   227             if (column < 0) {
   228                 column = 0;
   229             }
   230             if (column >= 9) {
   231                 column = 8;
   232             }
   233             if (row < 0) {
   234                 row = 0;
   235             }
   236             if (row > 8) {
   237                 row = 8;
   238             }
   239             Move m = Move.fence((char) ('A' + column), 1 + row, o);
   240             return m;
   241         }
   242 
   243         int round(int p, boolean cmpHori) {
   244     //        p = horizontal ? orig.x + p: orig.y + p;
   245             int onboard = p / 50;
   246             if (onboard < 0) {
   247                 onboard = 0;
   248             }
   249             if (onboard >= 9) {
   250                 return p;
   251             }
   252             int real = 25 + onboard * 50;
   253             if (horizontal != cmpHori) {
   254                 return real - 5;
   255             } else {
   256                 return real;
   257             }
   258         }
   259     }
   260 
   261     private static final class PlayerWidget extends Widget {
   262         public PlayerWidget(Scene s) {
   263             super(s);
   264         }
   265 
   266         @Override
   267         protected Rectangle calculateClientArea() {
   268             return getBounds();
   269         }
   270 
   271         @Override
   272         protected void paintWidget() {
   273             Graphics2D g = getGraphics();
   274             Rectangle b = getBounds();
   275             g.drawOval(b.x + 5, b.y + 5, b.width - 10, b.height - 10);
   276         }
   277     }
   278 }