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