如何使用 MouseListener。不工作图形用户界面

How to work with MouseListener. Don't work GUI

我正在尝试根据本教程编写简单的国际象棋应用程序:https://proghammer.wordpress.com/2010/08/10/chess01-dragging-game-pieces/ 我使用此代码并进行了一些更改,但它不起作用。我真的是 Java GUI 编程的新手,有人能告诉我我做错了什么吗?

更新: 我正在尝试纠正我的错误,当我问这个问题时,我试图调试它。我认为问题出在 ChessGame class 中。 mouseDragged() 之类的方法有效,但没有任何改变。件没有拖。我请求帮助解决这个问题。 代码太多了,但是这段代码只是为了提供完整的信息。我再说一遍,我认为问题在 ChessGame 或(可能在 ChessView),其他代码仅用于理解结构。

这是我的代码:

public class ChessView extends JPanel {

ChessBoard board;

private static final int BOARD_START_X = 220;
private static final int BOARD_START_Y = 120;

private static final int TILE_WIDTH = 45;
private static final int TILE_HEIGHT = 45;

private Image background;

public ChessView() {
    board = new ChessBoard();
    // load and set background image
    URL backgroundImg = getClass().getClassLoader().getResource("background.jpg");
    this.background = new ImageIcon(backgroundImg).getImage();


    // add mouse listeners to enable drag and drop
    ChessGame game = new ChessGame(board, this);
    this.addMouseListener(game);
    this.addMouseMotionListener(game);

    // create application frame and set visible
    //
    JFrame f = new JFrame();
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(this);
    f.setResizable(false);
    f.setSize(this.background.getWidth(null), this.background.getHeight(null));
}

public static void main(String[] args) {
    new ChessView();
}

@Override
protected void paintComponent(Graphics g) {
    g.drawImage(this.background, 0, 0, null);
    int row;
    for(int i = 0; i < board.getHeight(); i++) {
        for(int j = 0; j < board.getWidth(); j++) {
            Piece piece = board.getBoardAsArray()[i][j];
            if (piece.getClass() != EmptySquare.class) {
                if (piece.getColor() == other.Color.WHITE) {
                    if (piece.getClass() != Pawn.class) row = 7;
                    else row = 6;
                } else {
                    if (piece.getClass() != Pawn.class) row = 0;
                    else row = 1;
                }
                int x = BOARD_START_X + (TILE_WIDTH * j);
                int y = BOARD_START_Y + (TILE_HEIGHT * row);
                piece.setX(x);
                piece.setY(y);
                g.drawImage(piece.getImage(), x, y, null);

            }
        }
    }
}

public ChessBoard getBoard() {
    return board;
}
}

这是我的听众:

public class ChessGame implements MouseListener, MouseMotionListener {

private ChessBoard board;
private ChessView view;

private Piece dragPiece;
private int dragOffsetX;
private int dragOffsetY;


public ChessGame(ChessBoard board, ChessView chessGui) {
    this.board = board;
    this.view = chessGui;
}

@Override
public void mousePressed(MouseEvent e) {
    int x = e.getPoint().x;
    int y = e.getPoint().y;

    for(int i = 0; i < view.getBoard().getHeight(); i++) {
        for(int j = 0; j < view.getBoard().getWidth(); j++) {
            Piece piece = view.getBoard().getBoardAsArray()[i][j];
            if (piece.getClass() != EmptySquare.class) {
                if (mouseOverPiece(piece, x, y)) {
                    this.dragOffsetX = x - piece.getX();
                    this.dragOffsetY = y - piece.getY();
                    this.dragPiece = piece;
                    break;
                }
            }
        }
    }
}

/**
 * check whether the mouse is currently over this piece
 * @param piece the playing piece
 * @param x x coordinate of mouse
 * @param y y coordinate of mouse
 * @return true if mouse is over the piece
 */
private boolean mouseOverPiece(Piece piece, int x, int y) {
    return piece.getX() <= x
            && piece.getX()+piece.getWidth() >= x
            && piece.getY() <= y
            && piece.getY()+piece.getHeight() >= y;
}

@Override
public void mouseReleased(MouseEvent arg0) {
    this.dragPiece = null;
}

@Override
public void mouseDragged(MouseEvent evt) {
    if(this.dragPiece != null){
        this.dragPiece.setX(evt.getPoint().x - this.dragOffsetX);
        this.dragPiece.setY(evt.getPoint().y - this.dragOffsetY);
        this.view.repaint();
    }

}

@Override
public void mouseClicked(MouseEvent arg0) {}

@Override
public void mouseEntered(MouseEvent arg0) {}

@Override
public void mouseExited(MouseEvent arg0) {}

@Override
public void mouseMoved(MouseEvent arg0) {}

}

这是我的董事会代表:

public class ChessBoard {
private Piece[][] board = new Piece[8][8];

private final int WIDTH = 8;
private final int HEIGHT = 8;

//Write a NullPiece class or contain nulls is 2-5 rows?
public ChessBoard () {
    setStartBoard(); //rewrite
}

public int getHeight() {
    return HEIGHT;
}

public int getWidth() {
    return WIDTH;
}

public Piece[][] getBoardAsArray() {
    return board;
}

public ArrayList<Piece> getBoardAsArrayList() {
    ArrayList<Piece> list = new ArrayList<Piece>();
     for (int i = 0; i < WIDTH; i++) {
         for (int j = 0; j < HEIGHT; j++) {
             list.add(board[i][j]);
         }
     }
    return list;
}

Piece firstWhiteRook = new Rook(Color.WHITE);
Piece secondWhiteRook = new Rook(Color.WHITE);
Piece firstWhiteKnight = new Knight(Color.WHITE);
Piece secondWhiteKnight = new Knight(Color.WHITE);
Piece firstWhiteBishop = new Bishop(Color.WHITE);
Piece secondWhiteBishop = new Bishop(Color.WHITE);
Piece whiteQueen = new Queen(Color.WHITE);
Piece whiteKing = new King(Color.WHITE);
Piece firstWhitePawn = new Pawn(Color.WHITE);
Piece secondWhitePawn = new Pawn(Color.WHITE);
Piece thirdWhitePawn = new Pawn(Color.WHITE);
Piece fourthWhitePawn = new Pawn(Color.WHITE);
Piece fifthWhitePawn = new Pawn(Color.WHITE);
Piece sixthWhitePawn = new Pawn(Color.WHITE);
Piece seventhWhitePawn = new Pawn(Color.WHITE);
Piece eighthWhitePawn = new Pawn(Color.WHITE);

Piece firstBlackRook = new Rook(Color.BLACK);
Piece secondBlackRook = new Rook(Color.BLACK);
Piece firstBlackKnight = new Knight(Color.BLACK);
Piece secondBlackKnight = new Knight(Color.BLACK);
Piece firstBlackBishop = new Bishop(Color.BLACK);
Piece secondBlackBishop = new Bishop(Color.BLACK);
Piece blackQueen = new Queen(Color.BLACK);
Piece blackKing = new King(Color.BLACK);
Piece firstBlackPawn = new Pawn(Color.BLACK);
Piece secondBlackPawn = new Pawn(Color.BLACK);
Piece thirdBlackPawn = new Pawn(Color.BLACK);
Piece fourthBlackPawn = new Pawn(Color.BLACK);
Piece fifthBlackPawn = new Pawn(Color.BLACK);
Piece sixthBlackPawn = new Pawn(Color.BLACK);
Piece seventhBlackPawn = new Pawn(Color.BLACK);
Piece eighthBlackPawn = new Pawn(Color.BLACK);


//TODO: make this more beautiful?
public void setStartBoard() {

    //set color for each piece

    //add all pieces to board
    board[0][0] = firstBlackRook;
    board[0][1] = firstBlackKnight;
    board[0][2] = firstBlackBishop;
    board[0][3] = blackQueen;
    board[0][4] = blackKing;
    board[0][5] = secondBlackBishop;
    board[0][6] = secondBlackKnight;
    board[0][7] = secondBlackRook;

    board[1][0] = firstBlackPawn;
    board[1][1] = secondBlackPawn;
    board[1][2] = thirdBlackPawn;
    board[1][3] = fourthBlackPawn;
    board[1][4] = fifthBlackPawn;
    board[1][5] = sixthBlackPawn;
    board[1][6] = seventhBlackPawn;
    board[1][7] = eighthBlackPawn;


    board[7][0] = firstWhiteRook;
    board[7][1] = firstWhiteKnight;
    board[7][2] = firstWhiteBishop;
    board[7][3] = whiteQueen;
    board[7][4] = whiteKing;
    board[7][5] = secondWhiteBishop;
    board[7][6] = secondWhiteKnight;
    board[7][7] = secondWhiteRook;

    board[6][0] =  firstWhitePawn;
    board[6][1] =  secondWhitePawn;
    board[6][2] =  thirdWhitePawn;
    board[6][3] =  fourthWhitePawn;
    board[6][4] =  fifthWhitePawn;
    board[6][5] =  sixthWhitePawn;
    board[6][6] =  seventhWhitePawn;
    board[6][7] = eighthWhitePawn;

    for(int i = 2; i < 6; i++) {
        for(int j = 0; j < 8; j++) {
            board[i][j] = new EmptySquare(Color.EMPTY);
        }
    }


}

}

这是我的 Piece 实现:

public class PieceImpl implements Piece {

private int x;

private int y;

private static final String NAME = ""; // Only for getName(). Don't use.

private Color color;

private Image image;

public PieceImpl(Color color) {
    this.color = color;
}

public void setColor(Color color) {
    this.color = color;
}

public Color getColor() {
    return color;
}

public Image getImage() {
    return image;
}

public void setImage(Image image) {
    this.image = image;
}

public String toString() {
    if (this.getColor() == Color.BLACK) {
        return "b" + NAME;
    } else {
        return "w" + NAME;
    }
}

public int getX() {
    return x;
}

public void setX(int x) {
    this.x = x;
}

public int getY() {
    return y;
}

public void setY(int y) {
    this.y = y;
}

public int getWidth() {
    return image.getWidth(null);
}

public int getHeight() {
    return image.getHeight(null);
}
}

这是 king 实现的例子:

public class King extends PieceImpl implements Piece{
private static final String NAME = "K";

public King(Color color) {
    super(color);
    if (this.getColor() == Color.WHITE) {
        URL urlToImage = getClass().getClassLoader().getResource("wk.png");
        setImage(new ImageIcon(urlToImage).getImage());
    } else if (this.getColor() == Color.BLACK) {
        URL urlToImage = getClass().getClassLoader().getResource("bk.png");
        setImage(new ImageIcon(urlToImage).getImage());
    }
}

public String toString() {
    if (this.getColor() == Color.BLACK) {
        return "b" + NAME;
    } else {
        return "w" + NAME;
    }
}

我用枚举表示颜色class:

public enum Color {

BLACK("black", 0),
WHITE("white", 1),
EMPTY("empty", -1);

private final String name;
private final int id;

private Color(String name, int id) {
    this.name = name;
    this.id = id;
}

public String getName() {
    return this.name;
}

public int getID() {
    return this.id;
}

}

这不仅仅是我的代码,正如我所说的,我正在尝试通过教程学习。但我想使用我的董事会代表。当我 运行ning 应用程序时,它是 运行,我看到了 GUI,但鼠标事件不起作用。谁能告诉我哪里出错了,为什么鼠标事件不起作用?

从您分享的评论和调试信息中,我感觉您的 mouseListener 运行良好。所以问题出在其他地方。研究你的代码,我发现在你的 ChessView class' paintComponent 方法中,代码中的 piece 变量的 xy 辞职:

int x = BOARD_START_X + (TILE_WIDTH * j);
int y = BOARD_START_Y + (TILE_HEIGHT * row);
piece.setX(x);
piece.setY(y);

并将其绘制在棋盘上的xy位置。所以这基本上是在撤销你在 mouseListener :

中所做的事情
this.dragPiece.setX(evt.getPoint().x - this.dragOffsetX);
this.dragPiece.setY(evt.getPoint().y - this.dragOffsetY);

所以你应该有办法在 board class 的新位置

中设置 piece

你应该有一个系统来存储每个片段的 xy 的初始值,并且不应该在 paintComponent 并且应该调用

g.drawImage(piece.getImage(), piece.getX(), piece.getY(), null);