JPanel не отображается динамически внутри JLayeredPane

#java #swing #user-interface #jlayeredpane

#java #качать #пользовательский интерфейс #jlayeredpane

Вопрос:

Я создаю шахматную программу на Java. Я не могу отобразить JPanel, содержащую параметры продвижения, поверх JPanel, то есть платы.

Доска находится внутри JLayeredPane, и когда пешка достигает последнего квадрата, я создаю экземпляр панели PromotionOptions внутри обработчика событий и повторно проверяю. Но JPanel не отображается.

Я уже пытался установить правильный размер и местоположение для объекта JPanel, указав revalidate() , также использовал метод repaint () . Я также явно присвоил JLayeredPane макет null.

Все вопросы, которые уже были в stackoverflow, связанные с этим, были решены путем правильной настройки макета, что, по-видимому, не является проблемой здесь…

 // JLayeredPane created here...
class Game extends JFrame {

    Game() {
        super.setLayout(new TableLayout(new double[][]{{0.5, 475, 0.5}, {0.5, 475, 0.5}}));

        JLayeredPane layeredContainer = new JLayeredPane();
        layeredContainer.setLayout(null);

        Board board = new Board(layeredContainer);
        board.arrange();

        layeredContainer.add(board, 1);
        board.setSize(475, 475);

        super.add(layeredContainer, "1, 1");

        super.setSize(600, 600);
        super.setResizable(false);
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);


        super.validate();
    }
}
  

// PromotionOptions создан здесь…

 public class Board extends JPanel {
//skipping some irrelevant code...
private class PromotionOptions extends JPanel {

    private PromotionOptions(PieceColor color) {
        super.setSize(50,200);
        super.setBackground(Color.WHITE);
        super.setLayout(new GridLayout(4, 1));

        ImageIcon queenIcon = new ImageIcon(getClass().getResource("/pieceIcons/"   color.abbr   "Q.png"));
        ImageIcon rookIcon = new ImageIcon(getClass().getResource("/pieceIcons/"   color.abbr   "R.png"));
        ImageIcon bishopIcon = new ImageIcon(getClass().getResource("/pieceIcons/"   color.abbr   "B.png"));
        ImageIcon knightIcon = new ImageIcon(getClass().getResource("/pieceIcons/"   color.abbr   "N.png"));

        JLabel queenLabel = new JLabel(queenIcon);
        JLabel rookLabel = new JLabel(rookIcon);
        JLabel bishopLabel = new JLabel(bishopIcon);
        JLabel knightLabel = new JLabel(knightIcon);

        super.add(queenLabel);
        super.add(rookLabel);
        super.add(bishopLabel);
        super.add(knightLabel);
    }
}
// skipping some more irrelevant code...
private void executeMove(Tile clickedTile) {
// skip to where I create the PromotionOption object and add to layeredPane...
case PROMOTION:
                    moveMade.initialTile.removePiece();
                    JPanel promotionOptions = new PromotionOptions(colorToMove);
                    promotionOptions.setLocation(200,200);
                    layeredPaneContainer.add(promotionOptions, 2);
                    layeredPaneContainer.revalidate();
                    break;
// Some more code here
}
// End of Board class...
}
  

Из-за какой-то ошибки всякий раз, когда пешка достигает последней плитки, ничего не отображается, и приложение продолжает работать как есть.

Комментарии:

1. Перекрестная публикация: coderanch.com/t/708639/java /…

Ответ №1:

После нескольких часов безуспешной отладки я, наконец, каким-то образом заставил его работать правильно. Что я сделал, так это добавил метод SwingUtilities.invokeLater() и передал код внутри него следующим образом..

 case PROMOTION:
                    moveMade.initialTile.removePiece();
                    SwingUtilities.invokeLater(() -> {
                        JPanel promotionOptions = new PromotionOptions(colorToMove.opposite);
                        promotionOptions.setLocation(clickedTile.getLocation());
                        layeredPaneContainer.add(promotionOptions, 2);
                        layeredPaneContainer.revalidate();
                    });
                    break;