1

几个小时后的第二个问题

凯,所以我在 java 中制作国际象棋变体,我的控制台程序按我想要的方式工作,但现在我试图将它转换为摇摆 GUI,同时仍然保持控制台的东西完好无损。所以到目前为止,我有一个正方形数组,其中包含用于控制台的碎片,还有一个二维数组 JPanel,其中包含用于 GUI 的碎片。我还没有在 GUI 中实现移动部件,所以我仍然从控制台执行它,但是在我移动部件后实际的 GUI 没有更新......即使它在控制台上执行(对不起,如果这个令人困惑)。

GUI 由一个构造函数组成,该构造函数调用一些方法 drawBoard() 和 drawSidebar() 并设置大小、标题等……所以这就是 main 方法的样子:

public static void main(String args[]) {
    ChessGUI GUI = new ChessGUI();
    Board console = new Board();
    do {
        console.printBoard();
        console.getScore();
        console.getMove();
        GUI.boardPanel.revalidate();
        GUI.sidePanel.revalidate();
        GUI.repaint();
    } while (true);
}

和 drawBoard() 以防它有所不同:

public void drawBoard() {
    LayoutManager layout = new GridLayout(NUMBER_OF_ROWS, NUMBER_OF_COLS);
    boardPanel.setLayout(layout);
    boardPanel.setPreferredSize(new Dimension(200, 450));
    chessBoard = new JPanel[NUMBER_OF_ROWS][NUMBER_OF_COLS];
    for (int i = 0; i < NUMBER_OF_ROWS; i++) {
        for (int j = 0; j < NUMBER_OF_COLS; j++) {
            chessBoard[i][j] = new JPanel();
            chessBoard[i][j].setBackground(getColor(i,j));
            int index = i * 4 + j;
            if (!(boardArray.chessBoard[index].square.isEmpty())) {
                Piece piece = (Piece) boardArray.chessBoard[index].square.firstElement();
                chessBoard[i][j].add(new JLabel(piece.toString()));
            }
            boardPanel.add(chessBoard[i][j]);
        }
    }
}

repaint 和 revalidate 方法似乎根本没有调用,即使控制台正在更新:(

4

3 回答 3

4

我真的不明白你在做什么。但是每次移动时重新创建整个棋盘面板是没有意义的。所有 Swing 组件只能有一个父级,更简单的解决方案是将部件从一个面板移动到另一个面板。所以代码会是这样的:

previousPanel.remove( piece );
currentPanel.add( piece );
previousPanel.revalidate();
previousPanel.repaint();
currentPanel.revalidate();
于 2009-11-14T02:49:36.130 回答
2

看起来您实际上从未从“boardPanel”中删除任何内容,即使您正在重置其 LayoutManager。

一种更安全的方法可能是从其容器中删除“boardPanel”,然后为“boardPanel”创建一个新实例,将其添加到容器中,然后将其他 JPanel 片段添加到这个新的“boardPanel”中。实际上,您将在每次移动后重建整个 JPanel 层次结构。

正如您所注意到的,一旦您在将组件添加到容器后开始尝试添加/移动/删除组件,Swing 可能会非常挑剔。对于游戏,通常最好的方法是拥有 1 个 JComponent/Component 并使用 Java2D 方法在其上绘制。Swing 通常只用于基于表单的应用程序。

于 2009-11-13T22:06:01.660 回答
2

更改布局不会做任何事情。

您需要调用 boardPanel.removeChildren()

但是,这将非常缓慢。

真的,您应该做的是拥有自己的 JPanel,覆盖 paintComponent() 并使用 Java Graphics 将图像绘制到适当的尺寸。

于 2009-11-13T22:13:07.063 回答