Using Java2D to display the board
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 04 Sep 2010 21:58:56 +0200
changeset 2489bbf25021886
parent 247 57bd8b561a2e
child 249 47d62a3afe63
Using Java2D to display the board
visidor/pom.xml
visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
     1.1 --- a/visidor/pom.xml	Sat Sep 04 19:08:55 2010 +0200
     1.2 +++ b/visidor/pom.xml	Sat Sep 04 21:58:56 2010 +0200
     1.3 @@ -37,11 +37,6 @@
     1.4        <artifactId>quoridor</artifactId>
     1.5        <version>${quoridorVersion}</version>
     1.6      </dependency>
     1.7 -    <dependency>
     1.8 -      <groupId>org.netbeans.api</groupId>
     1.9 -      <artifactId>org-netbeans-api-visual</artifactId>
    1.10 -      <version>RELEASE65</version>
    1.11 -    </dependency>
    1.12    </dependencies>
    1.13  </project>
    1.14  
     2.1 --- a/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java	Sat Sep 04 19:08:55 2010 +0200
     2.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java	Sat Sep 04 21:58:56 2010 +0200
     2.3 @@ -32,22 +32,12 @@
     2.4  import cz.xelfi.quoridor.Move;
     2.5  import cz.xelfi.quoridor.Player;
     2.6  import java.awt.Color;
     2.7 +import java.awt.Font;
     2.8 +import java.awt.Graphics;
     2.9  import java.awt.Graphics2D;
    2.10 -import java.awt.Point;
    2.11  import java.awt.Rectangle;
    2.12  import javax.swing.JFrame;
    2.13  import javax.swing.JPanel;
    2.14 -import org.netbeans.api.visual.action.ActionFactory;
    2.15 -import org.netbeans.api.visual.action.MoveProvider;
    2.16 -import org.netbeans.api.visual.anchor.AnchorFactory;
    2.17 -import org.netbeans.api.visual.border.BorderFactory;
    2.18 -import org.netbeans.api.visual.widget.ConnectionWidget;
    2.19 -import org.netbeans.api.visual.widget.ImageWidget;
    2.20 -import org.netbeans.api.visual.widget.LabelWidget;
    2.21 -import org.netbeans.api.visual.widget.LayerWidget;
    2.22 -import org.netbeans.api.visual.widget.Scene;
    2.23 -import org.netbeans.api.visual.widget.Widget;
    2.24 -import org.openide.util.Exceptions;
    2.25  
    2.26  /**
    2.27   *
    2.28 @@ -55,7 +45,6 @@
    2.29   */
    2.30  final class Viewer extends JPanel {
    2.31      private Board board;
    2.32 -    private final Scene scene;
    2.33  
    2.34      public Viewer() {
    2.35          this(Board.empty());
    2.36 @@ -63,9 +52,6 @@
    2.37  
    2.38      private Viewer(Board b) {
    2.39          this.board = b;
    2.40 -        this.scene = new Scene();
    2.41 -        add(scene.createView());
    2.42 -        view(scene, board);
    2.43      }
    2.44  
    2.45  
    2.46 @@ -88,211 +74,77 @@
    2.47          f.setVisible(true);
    2.48      }
    2.49  
    2.50 -    private void view(Scene scene, Board b) {
    2.51 -        scene.removeChildren();
    2.52 -//        Scene layerBoard = scene;
    2.53 -        final LayerWidget layerLines = new LayerWidget(scene);
    2.54 -        scene.addChild(layerLines);
    2.55 -        final LayerWidget layerBoard = new LayerWidget(scene);
    2.56 -        layerLines.addChild(layerBoard);
    2.57 -        final int WDTH = 50;
    2.58 -        final int HGHT = 50;
    2.59 -//        conn.setSourceAnchor(ahoj);
    2.60 -        Widget[][] fields = new Widget[10][];
    2.61 -        for (int i = 0; i < fields.length; i++) {
    2.62 -            fields[i] = new Widget[10];
    2.63 -            for (int j = 0; j < fields[i].length; j++) {
    2.64 -                LabelWidget w = new LabelWidget(scene);
    2.65 -                w.setPreferredBounds(new Rectangle(i * WDTH, j * HGHT, WDTH, HGHT));
    2.66 -                layerBoard.addChild(w);
    2.67 -                fields[i][j] = w;
    2.68 -            }
    2.69 -        }
    2.70 -        for (int i = 0; i < fields.length; i++) {
    2.71 -            for (int j = 0; j < fields[i].length; j++) {
    2.72 -                if (i > 0) {
    2.73 -                    ConnectionWidget horiz = new ConnectionWidget(scene);
    2.74 -                    horiz.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i - 1][j]));
    2.75 -                    horiz.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
    2.76 -                    scene.addChild(horiz);
    2.77 -                }
    2.78 -                if (j > 0) {
    2.79 -                    ConnectionWidget vert = new ConnectionWidget(scene);
    2.80 -                    vert.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i][j - 1]));
    2.81 -                    vert.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
    2.82 -                    scene.addChild(vert);
    2.83 -                }
    2.84 +    @Override
    2.85 +    protected void paintComponent(Graphics gg) {
    2.86 +        int fieldSize = Math.min(getSize().width, getSize().height) / 9;
    2.87 +        int fifth = fieldSize / 10;
    2.88 +        Graphics2D g = (Graphics2D) gg;
    2.89 +        
    2.90 +        int xdelta = getSize().width - fieldSize * 9;
    2.91 +        int ydelta = getSize().height - fieldSize * 9;
    2.92 +        
    2.93 +        g.translate(xdelta / 2, ydelta / 2);
    2.94 +
    2.95 +        g.setColor(Color.lightGray);
    2.96 +        for (int i = 0; i < 9; i++) {
    2.97 +            for (int j = 0; j < 9; j++) {
    2.98 +                final Rectangle r = new Rectangle(i * fieldSize, j * fieldSize, fieldSize, fieldSize);
    2.99 +                g.fillRect(r.x + fifth, r.y + fifth, r.width - fifth * 2, r.height - fifth * 2);
   2.100              }
   2.101          }
   2.102  
   2.103 -        ImageWidget horizontalWall = new ImageWidget(scene);
   2.104 -        horizontalWall.setPreferredBounds(new Rectangle(550, 300, 90, 10));
   2.105 -        horizontalWall.setBackground(Color.BLACK);
   2.106 -        horizontalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(true)));
   2.107 -        horizontalWall.setBorder(BorderFactory.createLineBorder());
   2.108 -        horizontalWall.setOpaque(true);
   2.109 -        layerBoard.addChild(horizontalWall);
   2.110  
   2.111 -        ImageWidget verticalWall = new ImageWidget(scene);
   2.112 -        verticalWall.setPreferredBounds(new Rectangle(600, 150, 10, 90));
   2.113 -        verticalWall.setBackground(Color.BLACK);
   2.114 -        verticalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(false)));
   2.115 -        verticalWall.setBorder(BorderFactory.createLineBorder());
   2.116 -        verticalWall.setOpaque(true);
   2.117 -        layerBoard.addChild(verticalWall);
   2.118 -
   2.119 -        for (Fence f : b.getFences()) {
   2.120 -            Rectangle r = fenceRectangle(f.getColumn(), f.getRow(), f.getOrientation());
   2.121 -            ImageWidget fenceWall = new ImageWidget(scene);
   2.122 -            fenceWall.setPreferredBounds(r);
   2.123 -            fenceWall.setBackground(Color.BLACK);
   2.124 -            fenceWall.setBorder(BorderFactory.createLineBorder());
   2.125 -            fenceWall.setOpaque(true);
   2.126 -            layerBoard.addChild(fenceWall);
   2.127 +        g.setColor(Color.BLACK);
   2.128 +        for (Fence f : board.getFences()) {
   2.129 +            int w, h;
   2.130 +            switch (f.getOrientation()) {
   2.131 +                case HORIZONTAL: w = fieldSize - fifth; h = fifth; break;
   2.132 +                case VERTICAL: w = fifth; h = fieldSize - fifth; break;
   2.133 +                default: throw new IllegalStateException();
   2.134 +            }
   2.135 +            int column = (f.getColumn() - 'A') + 1;
   2.136 +            int row = 9 - f.getRow();
   2.137 +            Rectangle r = new Rectangle(
   2.138 +                column * fieldSize - w,
   2.139 +                row * fieldSize - h,
   2.140 +                2 * w,
   2.141 +                2 * h
   2.142 +            );
   2.143 +            g.fill(r);
   2.144          }
   2.145  
   2.146          int cnt = 0;
   2.147 -        for (Player p : b.getPlayers()) {
   2.148 -            LabelWidget lw = new LabelWidget(scene);
   2.149 -            lw.setLabel("" + p.getFences());
   2.150 -            if (cnt == 0) {
   2.151 -                lw.setPreferredBounds(new Rectangle(550, 200, 50, 50));
   2.152 -            } else {
   2.153 -                lw.setPreferredBounds(new Rectangle(550, 450, 50, 50));
   2.154 +        Color[] colors = { Color.WHITE, Color.BLACK, Color.ORANGE, Color.MAGENTA };
   2.155 +        int diametr = fieldSize - fifth * 4;
   2.156 +        for (Player p : board.getPlayers()) {
   2.157 +            int column = p.getColumn();
   2.158 +            int row = 8 - p.getRow();
   2.159 +            final Rectangle r = new Rectangle(
   2.160 +                column * fieldSize + 2 * fifth,
   2.161 +                row * fieldSize + 2 * fifth,
   2.162 +                diametr,
   2.163 +                diametr
   2.164 +            );
   2.165 +            g.setColor(colors[cnt]);
   2.166 +            g.fillOval(r.x, r.y, r.width, r.height);
   2.167 +            if (p == board.getCurrentPlayer()) {
   2.168 +                g.setColor(Color.lightGray);
   2.169 +                g.fillOval(r.x + r.width / 3, r.y + r.height / 3, r.width / 3, r.height / 3);
   2.170              }
   2.171 -            layerBoard.addChild(lw);
   2.172 +            cnt++;
   2.173 +        }
   2.174  
   2.175 -            PlayerWidget pw = new PlayerWidget(scene);
   2.176 -            System.err.println("p: " + p);
   2.177 -            pw.setPreferredBounds(new Rectangle(p.getColumn() * 50 + 25, p.getRow() * 50 + 25, 50, 50));
   2.178 -            layerBoard.addChild(pw);
   2.179 -
   2.180 -            cnt++;
   2.181 +        g.setColor(Color.BLACK);
   2.182 +        final Font f = new Font("Monospace", Font.BOLD, fifth * 2);
   2.183 +        g.setFont(f);
   2.184 +        for (int i = 0; i < 8; i++) {
   2.185 +            final char ch = (char) ('A' + i);
   2.186 +            g.drawString(Character.toString(ch), i * fieldSize + fieldSize - fifth, fifth + f.getSize() - f.getBaselineFor(ch));
   2.187 +        }
   2.188 +        for (int i = 0; i < 8; i++) {
   2.189 +            String s = "" + (8 - i);
   2.190 +            g.drawString(s, fifth, i * fieldSize + fieldSize - fifth + f.getSize() - f.getBaselineFor(s.charAt(0)));
   2.191          }
   2.192      }
   2.193  
   2.194 -    private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) {
   2.195 -        int w, h;
   2.196 -        switch (o) {
   2.197 -            case HORIZONTAL: w = 45; h = 5; break;
   2.198 -            case VERTICAL: w = 5; h = 45; break;
   2.199 -            default: throw new IllegalStateException();
   2.200 -        }
   2.201 -
   2.202 -        return new Rectangle(
   2.203 -            (column - 'A' + 1) * 50 + 25 - w, row * 50 + 25 - h, 2 * w, 2 * h
   2.204 -        );
   2.205 -    }
   2.206 -
   2.207 -    private class MoveControl implements MoveProvider {
   2.208 -        final boolean horizontal;
   2.209 -
   2.210 -        Point orig;
   2.211 -
   2.212 -        private MoveControl(boolean horizontal) {
   2.213 -            this.horizontal = horizontal;
   2.214 -        }
   2.215 -        public void movementStarted(Widget widget) {
   2.216 -            System.err.println("started: " + widget.getBounds());
   2.217 -        }
   2.218 -
   2.219 -        public void movementFinished(Widget widget) {
   2.220 -            try {
   2.221 -                final Rectangle bounds = widget.getBounds();
   2.222 -                final Move m = createMoveForDrop( bounds);
   2.223 -                System.err.println("finish: " + m);
   2.224 -                board = board.apply(m);
   2.225 -            } catch (IllegalPositionException ex) {
   2.226 -                Exceptions.printStackTrace(ex);
   2.227 -            }
   2.228 -
   2.229 -            view(scene, board);
   2.230 -        }
   2.231 -
   2.232 -        public Point getOriginalLocation(Widget widget) {
   2.233 -            final Rectangle b = widget.getBounds();
   2.234 -            orig = new Point(b.x, b.y);
   2.235 -            try {
   2.236 -                System.err.println("  where: " + createMoveForDrop(b));
   2.237 -            } catch (IllegalPositionException ex) {
   2.238 -                Exceptions.printStackTrace(ex);
   2.239 -            }
   2.240 -            return orig;
   2.241 -        }
   2.242 -
   2.243 -        public void setNewLocation(Widget widget, Point location) {
   2.244 -            final Rectangle b = new Rectangle(
   2.245 -                round(location.x, true) + (horizontal ? 5 : 0),
   2.246 -                round(location.y, false) + (horizontal ? 0 : 5),
   2.247 -                horizontal ? 90 : 10,
   2.248 -                horizontal ? 10 : 90
   2.249 -            );
   2.250 -            widget.setPreferredBounds(b);
   2.251 -            try {
   2.252 -                System.err.println("move: " + createMoveForDrop(b));
   2.253 -            } catch (IllegalPositionException ex) {
   2.254 -                System.err.println("no move");
   2.255 -            }
   2.256 -        }
   2.257 -
   2.258 -        Move createMoveForDrop(final Rectangle bounds) throws IllegalPositionException {
   2.259 -            int column = bounds.x / 50;
   2.260 -            int row = bounds.y / 50;
   2.261 -            Orientation o = bounds.width > bounds.height ? Orientation.HORIZONTAL : Orientation.VERTICAL;
   2.262 -            switch (o) {
   2.263 -                case HORIZONTAL: row--; break;
   2.264 -                case VERTICAL: column--; break;
   2.265 -                default: assert false;
   2.266 -            }
   2.267 -            if (column < 0) {
   2.268 -                column = 0;
   2.269 -            }
   2.270 -            if (column >= 9) {
   2.271 -                column = 8;
   2.272 -            }
   2.273 -            if (row < 0) {
   2.274 -                row = 0;
   2.275 -            }
   2.276 -            if (row > 8) {
   2.277 -                row = 8;
   2.278 -            }
   2.279 -            Move m = Move.fence((char) ('A' + column), 1 + row, o);
   2.280 -            return m;
   2.281 -        }
   2.282 -
   2.283 -        int round(int p, boolean cmpHori) {
   2.284 -    //        p = horizontal ? orig.x + p: orig.y + p;
   2.285 -            int onboard = p / 50;
   2.286 -            if (onboard < 0) {
   2.287 -                onboard = 0;
   2.288 -            }
   2.289 -            if (onboard >= 9) {
   2.290 -                return p;
   2.291 -            }
   2.292 -            int real = 25 + onboard * 50;
   2.293 -            if (horizontal != cmpHori) {
   2.294 -                return real - 5;
   2.295 -            } else {
   2.296 -                return real;
   2.297 -            }
   2.298 -        }
   2.299 -    }
   2.300 -
   2.301 -    private static final class PlayerWidget extends Widget {
   2.302 -        public PlayerWidget(Scene s) {
   2.303 -            super(s);
   2.304 -        }
   2.305 -
   2.306 -        @Override
   2.307 -        protected Rectangle calculateClientArea() {
   2.308 -            return getBounds();
   2.309 -        }
   2.310 -
   2.311 -        @Override
   2.312 -        protected void paintWidget() {
   2.313 -            Graphics2D g = getGraphics();
   2.314 -            Rectangle b = getBounds();
   2.315 -            g.drawOval(b.x + 5, b.y + 5, b.width - 10, b.height - 10);
   2.316 -        }
   2.317 -    }
   2.318  }