Java - 在返回结果之前等待有效的一系列点击

时间:2014-04-10 20:16:36

标签: java multithreading events user-interface mouseevent

我正在研究国际象棋的Java版本。我已经做了几年的程序员,但从未收到过面向对象,基于事件的编程的精彩解释。

这是我的问题:我当前的程序是一个线性的,控制台驱动的游戏,用户输入一种颜色的移动,而计算机为另一种颜色移动。为此,我有一个带有“getMove”方法的通用“Player”类。 HumanPlayer从控制台输入中移动,AIPlayer从算法生成移动。

我现在正在尝试创建第三种类型的播放器GUIPlayer,它可以从GUI事件中生成移动。这就是我想要发生的事情:

Game ---(request for move)---> GUIPlayer --------(request for move)---------> GUI
  ^------(resulting move)--------|<-----(resulting move from click events)-----|

换句话说,游戏允许玩家有限制地访问GUI以请求移动,然后玩家等待直到满足GUI中的特定条件。我喜欢这个设计,但我不确定如何实现它。我假设Player类或GUI需要某种线程等待通知结构。

这是我的代码的简化版本。这是一个非常粗略的原型,专门用于返回移动。

public class ChessPanel
    extends Component
    implements MouseListener, MouseMotionListener {

Board b;
Piece selectedPiece;
Position selectedPiecePosition;
Move playerMove;

public void mouseClicked(MouseEvent e) {
    Position clickPosition = getSquare(e.getX(), e.getY());

    if(this.selectedPiece.getType() == PieceType.NONE) {
        // Attempts to select the piece that was just clicked
        Piece piece = b.getPiece(clickPosition);

        System.out.println("Selected "+piece);

        if(piece.getType() != PieceType.NONE) {
            this.selectedPiece = b.getPiece(clickPosition);
            this.selectedPiecePosition = clickPosition;
        }
    } else {
        // Attempts to move the selected piece
        try {
            this.playerMove = b.getMove(selectedPiecePosition, clickPosition);

            System.out.println("Made a VALID move");
        } catch(InvalidMoveException ex) {
            // Deselects the selected piece if move is invalid
            this.selectedPiece = new NonePiece();

            System.out.println("Made an INVALID move");
        }
    }
}

}

基本上,我希望GUIPlayer等到(playerMove!= null)将其作为移动返回。这听起来像是好设计吗?如果是这样,我该如何实现呢?

1 个答案:

答案 0 :(得分:0)

GOT IT。

原来这是一个基本的等待通知问题。这是我的ChessPanel&#34; mouseClicked&#34;的最终代码。方法:

public void mouseClicked(MouseEvent e) {
    Position clickPosition = getSquare(e.getX(), e.getY());

    if(this.selectedPiece.getType() == PieceType.NONE) {
        // Attempts to select the piece that was just clicked
        Piece piece = b.getPiece(clickPosition);

        if(piece.getType() != PieceType.NONE) {
            this.selectedPiece = b.getPiece(clickPosition);
            this.selectedPiecePosition = clickPosition;
        }
    } else {
        // Attempts to move the selected piece
        try {
            this.playerMove = b.getMove(selectedPiecePosition, clickPosition);
            synchronized(this) {
                this.notify();
            }
        } catch(InvalidMoveException ex) {

        }
        this.selectedPiece = new NonePiece();
        this.selectedPiecePosition = new Position(0, 0);
        updateCurrentHover(e.getX(), e.getY());
    }

    repaint();
}

对于GUI本身:

    while(cp.getMove() == null) {
        try {
            synchronized(cp) {
                cp.wait();
            }
        } catch (InterruptedException e) {}
    }

这解决了它。