Official API for BoardPane with listener to react to user gestures.
1.1 --- a/visidor/pom.xml Sun Sep 05 17:58:45 2010 +0200
1.2 +++ b/visidor/pom.xml Sun Sep 05 22:34:43 2010 +0200
1.3 @@ -4,7 +4,6 @@
1.4 <artifactId>visidor</artifactId>
1.5 <packaging>jar</packaging>
1.6 <version>${visidorVersion}</version>
1.7 - <name>visidor</name>
1.8 <url>http://maven.apache.org</url>
1.9 <parent>
1.10 <groupId>cz.xelfi.quoridor</groupId>
1.11 @@ -23,6 +22,18 @@
1.12 <target>1.5</target>
1.13 </configuration>
1.14 </plugin>
1.15 + <plugin>
1.16 + <groupId>org.apache.felix</groupId>
1.17 + <artifactId>maven-bundle-plugin</artifactId>
1.18 + <version>2.0.1</version>
1.19 + <extensions>true</extensions>
1.20 + <configuration>
1.21 + <instructions>
1.22 + <Export-Package>cz.xelfi.quoridor.visidor</Export-Package>
1.23 + <Private-Package>cz.xelfi.quoridor.visitor.*</Private-Package>
1.24 + </instructions>
1.25 + </configuration>
1.26 + </plugin>
1.27 </plugins>
1.28 </build>
1.29 <dependencies>
1.30 @@ -38,6 +49,8 @@
1.31 <version>${quoridorVersion}</version>
1.32 </dependency>
1.33 </dependencies>
1.34 + <name>Quoridor Visual Board</name>
1.35 + <description>Provides Swing component to display and interact with quoridor board.</description>
1.36 </project>
1.37
1.38
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardEvent.java Sun Sep 05 22:34:43 2010 +0200
2.3 @@ -0,0 +1,30 @@
2.4 +/*
2.5 + * To change this template, choose Tools | Templates
2.6 + * and open the template in the editor.
2.7 + */
2.8 +
2.9 +package cz.xelfi.quoridor.visidor;
2.10 +
2.11 +import cz.xelfi.quoridor.Move;
2.12 +import java.util.EventObject;
2.13 +
2.14 +/** Event describing what happens in {@link BoardPane}.
2.15 + *
2.16 + * @author Jaroslav Tulach <jtulach@netbeans.org>
2.17 + */
2.18 +public final class BoardEvent extends EventObject {
2.19 + private final Move move;
2.20 +
2.21 + BoardEvent(BoardPane p, Move m) {
2.22 + super(p);
2.23 + this.move = m;
2.24 + }
2.25 +
2.26 + /** The move that describes recent user gesture on the {@link BoardPane}.
2.27 + *
2.28 + * @return the move or null, if this event does not describe a move
2.29 + */
2.30 + public Move getMove() {
2.31 + return move;
2.32 + }
2.33 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardListener.java Sun Sep 05 22:34:43 2010 +0200
3.3 @@ -0,0 +1,20 @@
3.4 +/*
3.5 + * To change this template, choose Tools | Templates
3.6 + * and open the template in the editor.
3.7 + */
3.8 +
3.9 +package cz.xelfi.quoridor.visidor;
3.10 +
3.11 +import java.util.EventListener;
3.12 +
3.13 +/** Channel referring back what happens in a {@link BoardPane}.
3.14 + *
3.15 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.16 + */
3.17 +public interface BoardListener extends EventListener {
3.18 + /** Notifies listeners about a change in the {@link BoardPane}.
3.19 + *
3.20 + * @param ev the event, usually next move applicable to the board
3.21 + */
3.22 + public void boardChanged(BoardEvent ev);
3.23 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardPane.java Sun Sep 05 22:34:43 2010 +0200
4.3 @@ -0,0 +1,65 @@
4.4 +/*
4.5 + * To change this template, choose Tools | Templates
4.6 + * and open the template in the editor.
4.7 + */
4.8 +
4.9 +package cz.xelfi.quoridor.visidor;
4.10 +
4.11 +import cz.xelfi.quoridor.Board;
4.12 +import cz.xelfi.quoridor.Move;
4.13 +import java.awt.GridLayout;
4.14 +import java.util.List;
4.15 +import java.util.concurrent.CopyOnWriteArrayList;
4.16 +import javax.swing.JPanel;
4.17 +
4.18 +/** JavaBean class that displays and can manipulate with Quoridor {@link Board}.
4.19 + *
4.20 + * @author Jaroslav Tulach <jtulach@netbeans.org>
4.21 + */
4.22 +public final class BoardPane extends JPanel {
4.23 + private final Viewer viewer;
4.24 + private final List<BoardListener> listeners = new CopyOnWriteArrayList<BoardListener>();
4.25 +
4.26 + public BoardPane() {
4.27 + setLayout(new GridLayout(1,1));
4.28 + viewer = new Viewer();
4.29 + viewer.moveListener(this);
4.30 + add(viewer);
4.31 + }
4.32 +
4.33 + public final void setBoard(Board b) {
4.34 + viewer.setBoard(b);
4.35 + }
4.36 +
4.37 + public final Board getBoard() {
4.38 + return viewer.getBoard();
4.39 + }
4.40 +
4.41 + /** The board can either be in <q>view only</q> mode when showing state
4.42 + * of the {@link Board} during opponent's move, or it can be editable.
4.43 + * In editable mode, one shall listen on changes delivered to
4.44 + * BoardListener.
4.45 + *
4.46 + * @param editable read only or editable mode?
4.47 + */
4.48 + public final void setEditable(boolean editable) {
4.49 + viewer.enableListeners(editable);
4.50 + }
4.51 +
4.52 + public final void addBoardListener(BoardListener l) {
4.53 + listeners.add(l);
4.54 + }
4.55 + public final void removeBoardListener(BoardListener l) {
4.56 + listeners.remove(l);
4.57 + }
4.58 +
4.59 + final void moveHappened(Move m) {
4.60 + BoardEvent ev = null;
4.61 + for (BoardListener bl : listeners) {
4.62 + if (ev == null) {
4.63 + ev = new BoardEvent(this, m);
4.64 + }
4.65 + bl.boardChanged(ev);
4.66 + }
4.67 + }
4.68 +}
5.1 --- a/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Sun Sep 05 17:58:45 2010 +0200
5.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Sun Sep 05 22:34:43 2010 +0200
5.3 @@ -55,6 +55,7 @@
5.4 private int xdelta;
5.5 private int ydelta;
5.6 private Orientation lastOrientation;
5.7 + private BoardPane pane;
5.8
5.9 public Viewer() {
5.10 this(Board.empty());
5.11 @@ -62,8 +63,6 @@
5.12
5.13 private Viewer(Board b) {
5.14 this.board = b;
5.15 - addMouseMotionListener(this);
5.16 - addMouseListener(this);
5.17 }
5.18
5.19
5.20 @@ -71,10 +70,24 @@
5.21 * @param args the command line arguments
5.22 */
5.23 public static void main(String[] args) throws IllegalPositionException {
5.24 - Board b = Board.empty();
5.25 JFrame f = new JFrame();
5.26 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
5.27 - f.add(new Viewer(b));
5.28 + final BoardPane bp = new BoardPane();
5.29 + class ApplyMove implements BoardListener {
5.30 + public void boardChanged(BoardEvent ev) {
5.31 + Move m = ev.getMove();
5.32 + if (m != null) {
5.33 + try {
5.34 + bp.setBoard(bp.getBoard().apply(m));
5.35 + } catch (IllegalPositionException ex) {
5.36 + // no new move
5.37 + }
5.38 + }
5.39 + }
5.40 + }
5.41 + bp.addBoardListener(new ApplyMove());
5.42 + bp.setEditable(true);
5.43 + f.add(bp);
5.44 f.pack();
5.45 f.setVisible(true);
5.46 }
5.47 @@ -259,13 +272,9 @@
5.48
5.49 public void mousePressed(MouseEvent e) {
5.50 Move m = redrawCurrentMove(e);
5.51 - if (m != null) {
5.52 - try {
5.53 - board = board.apply(m);
5.54 - } catch (IllegalPositionException ex) {
5.55 - // no new move
5.56 - }
5.57 - repaint();
5.58 + BoardPane bp = pane;
5.59 + if (bp != null) {
5.60 + bp.moveHappened(m);
5.61 }
5.62 }
5.63
5.64 @@ -278,4 +287,29 @@
5.65 public void mouseExited(MouseEvent e) {
5.66 }
5.67
5.68 + final void setBoard(Board b) {
5.69 + board = b;
5.70 + if (isShowing()) {
5.71 + repaint();
5.72 + }
5.73 + }
5.74 +
5.75 + final Board getBoard() {
5.76 + return board;
5.77 + }
5.78 +
5.79 + final void enableListeners(boolean editable) {
5.80 + if (editable) {
5.81 + addMouseMotionListener(this);
5.82 + addMouseListener(this);
5.83 + } else {
5.84 + removeMouseListener(this);
5.85 + removeMouseMotionListener(this);
5.86 + }
5.87 + }
5.88 +
5.89 + final void moveListener(BoardPane pane) {
5.90 + this.pane = pane;
5.91 + }
5.92 +
5.93 }