Official API for BoardPane with listener to react to user gestures.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 05 Sep 2010 22:34:43 +0200
changeset 2559ecd02d694cd
parent 254 1273bfb0e2e7
child 256 1758a7727278
Official API for BoardPane with listener to react to user gestures.
visidor/pom.xml
visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardEvent.java
visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardListener.java
visidor/src/main/java/cz/xelfi/quoridor/visidor/BoardPane.java
visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
     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  }