将 JLabel 从一个 JPanel 拖到另一个 JPanel 时遇到问题

问题描述

我正在尝试使用 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 (将#修改为@)