问题描述
我正在尝试使用 Swing 开发一个用于 GUI 的 Java 国际象棋引擎,最近几天我发现了一些挫折。该引擎已经功能齐全,并且与点击移动完美配合(在 Tile-JPanel 上单击您想要移动的棋子,再次单击要放置棋子的 Tile-JPanel)。现在我愿意更进一步,并决定实现拖放动作(在所需的 JPanel 上单击并按住鼠标、拖动和释放)。
这是我发现问题的地方。我的移动类具有以下参数:棋盘配置、移动的起始图块和结束图块。当我按下鼠标时,它会获取源磁贴 ID,但是当我释放它时,目标磁贴 ID 也是源磁贴 ID。这让我的引擎认为我试图将碎片移动到同一个瓷砖上,从而导致非法移动。我已经尝试使用 destinationTile = chessBoard.getTile(tileId)
与我用于点击移动的相同概念,但它采用的是源磁贴。我试过使用 TilePanel obj = (TilePanel)e.getSource(); destinationTile = chessBoard.getTile(obj.getTileId());
并且这样,源和目标磁贴都获得了片标识符的值?因此,如果我尝试拖放一个棋子,它们都会得到“P”作为值,如果我尝试移动皇后,它们会得到“Q”。所以是的,我完全迷失了。
我面临的第二个问题是拖动 Piece-JLabel 时,它仅限于它所在的 Tile-JPanel 的边界。这是意料之中的,所以我尝试使用 JlayeredPane。
我的方法是,克隆移动的一块-JLabel,将原来的一块设置为不可见。将克隆的一个添加到 JlayeredPane.DRAG_LAYER
,跟随鼠标拖动它。并且在发布时,如果给定的移动是合法的,则将此 JLabel 放在目标磁贴 JPanel 上并删除源磁贴上的不可见 JLabel。这也没有成功,因为无论我如何尝试将 JLabel 添加到 DRAG_LAYER 我都无法让它工作。无论我尝试什么,我都无法获得一块图像来跟随我的光标在板上移动。
这是我的大部分 Tile 类以及所有 MouseEvent 处理程序:
private class TilePanel extends JPanel {
private final int tileId;
public int getTileId() {
return tileId;
}
TilePanel(final BoardPanel boardPanel,final int tileId) throws IOException {
super(new GridBagLayout());
this.tileId = tileId;
setPreferredSize(TILE_PANEL_DIMENSION);
assignTileColor();
assignTilePieceIcon(chessBoard);
highlightTileBorder(chessBoard);
addMouseListener(new MouseListener() {
@Override
public void mouseClicked(final MouseEvent e) {
if(isRightMouseButton(e)) {
sourceTile = null;
destinationTile = null;
humanMovedPiece = null;
try {
boardPanel.drawBoard(chessBoard);
} catch (IOException ioException) {
ioException.printstacktrace();
}
System.out.println("piece deselected");
}
else if (isLeftMouseButton(e)) {
if(sourceTile == null) {
//first click
sourceTile = chessBoard.getTile(tileId);
humanMovedPiece = sourceTile.getPiece();
if (humanMovedPiece == null) {
sourceTile = null;
}
System.out.println("piece selected");
}
else {
//second click
destinationTile = chessBoard.getTile(tileId);
final Move move = Move.MoveFactory.createMove(chessBoard,sourceTile.getTileCoordinate(),destinationTile.getTileCoordinate());
final MoveTransition transition = chessBoard.getCurrentPlayer().makeMove(move);
if (transition.getMoveStatus() == MoveStatus.DONE) {
chessBoard = transition.getTransitionBoard();
moveLog.addMove(move);
SFXUtils.playSound("move");
System.out.println(chessBoard);
System.out.println("█████ move done: " + move.toString() + " █████");
}
sourceTile = null;
destinationTile = null;
humanMovedPiece = null;
}
SwingUtilities.invokelater(new Runnable() {
@Override
public void run() {
try {
gameHistoryPanel.redo(chessBoard,moveLog);
takenPiecesPanel.redo(moveLog);
boardPanel.drawBoard(chessBoard);
} catch (IOException ioException) {
ioException.printstacktrace();
}
}
});
}
}
@Override
public void mousepressed(final MouseEvent e) {
if(sourceTile == null) {
//first click
sourceTile = chessBoard.getTile(tileId);
System.out.println(tileId);
System.out.println(sourceTile.getTileCoordinate());
humanMovedPiece = sourceTile.getPiece();
if (humanMovedPiece == null) {
sourceTile = null;
}
System.out.println("piece selected");
}
SwingUtilities.invokelater(new Runnable() {
@Override
public void run() {
try {
gameHistoryPanel.redo(chessBoard,moveLog);
takenPiecesPanel.redo(moveLog);
boardPanel.drawBoard(chessBoard);
} catch (IOException ioException) {
ioException.printstacktrace();
}
}
});
}
@Override
public void mouseReleased(final MouseEvent e) {
/* TilePanel obj = (TilePanel)e.getSource();
destinationTile = chessBoard.getTile(obj.getTileId());*/
destinationTile = chessBoard.getTile(tileId);
final Move move = Move.MoveFactory.createMove(chessBoard,destinationTile.getTileCoordinate());
final MoveTransition transition = chessBoard.getCurrentPlayer().makeMove(move);
if (transition.getMoveStatus() == MoveStatus.DONE) {
chessBoard = transition.getTransitionBoard();
moveLog.addMove(move);
SFXUtils.playSound("move");
System.out.println(chessBoard);
System.out.println("█████ move done: " + move.toString() + " █████");
}
sourceTile = null;
destinationTile = null;
humanMovedPiece = null;
SwingUtilities.invokelater(new Runnable() {
@Override
public void run() {
try {
gameHistoryPanel.redo(chessBoard,moveLog);
takenPiecesPanel.redo(moveLog);
boardPanel.drawBoard(chessBoard);
} catch (IOException ioException) {
ioException.printstacktrace();
}
}
});
}
@Override
public void mouseEntered(final MouseEvent e) {
}
@Override
public void mouseExited(final MouseEvent e) {
}
});
addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(final MouseEvent e) {
System.out.println("im draggin");
TilePanel obj = (TilePanel)e.getSource();
JLabel draggedPieceImageLabel = (JLabel) obj.getComponent(0);
//obj.getComponent(0).setVisible(false);
draggedPieceImageLabel.setLocation(e.getX()-25,e.getY()-25);
add(draggedPieceImageLabel);
}
@Override
public void mouseMoved(MouseEvent e) {
}
});
validate();
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)