1

我的应用程序的 JFrame 逻辑如下所示:

public Table() {
    super("Chess");
    thisFrame = this;
    tableMenuBar = new JMenuBar();
    populateMenuBar();
    setJMenuBar(tableMenuBar);
    getContentPane().setLayout(new BorderLayout());
    chessBoard = new Board(new StandardBoardConfigurator());
    gamePanel = new GameHistoryPanel();
    chatPanel = new ChatPanel();
    takenPiecesPanel = new TakenPiecesPanel();
    boardPanel = new BoardPanel(chessBoard);
    gameProgress = 1;
    highlightLegalMoves = true;
    moveLog = new ArrayList<Move>();
    gameOver = false;
    getContentPane().add(takenPiecesPanel, BorderLayout.WEST);
    getContentPane().add(boardPanel, BorderLayout.CENTER);
    getContentPane().add(gamePanel, BorderLayout.EAST);
    getContentPane().add(chatPanel, BorderLayout.SOUTH);
    // Make sure we have nice window decorations.
    setDefaultLookAndFeelDecorated(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(OUTER_FRAME_DIMENSION);
    pack();
    setVisible(true);
}

并且JPanel包含 JTable 是“GameHistoryPanel”,它的构造函数逻辑如下:

    public GameHistoryPanel() {
        this.setLayout(new BorderLayout());
        this.model = new DataModel();
        this.table = new JTable(model);
        this.table.setRowHeight(15);
        final JScrollPane scrollPane = new JScrollPane(this.table);
        scrollPane.setColumnHeaderView(table.getTableHeader());
        scrollPane.setPreferredSize(HISTORY_PANEL_DIMENSION);
        this.add(scrollPane, BorderLayout.CENTER);
        this.currentRow = 0;
        this.currentColumn = 0;
        this.setVisible(true);
    }

具有以下更新例程,每当进行移动时都会GamePanel调用:setValueAt

    public void increment(final Board board,
                          final Move move) {
        this.model.setValueAt(move, currentRow, currentColumn);
        if(board.currentPlayer().getAlliance() == Alliance.WHITE) {
            currentColumn++;
        } else if (board.currentPlayer().getAlliance() == Alliance.BLACK) {
            currentRow++;
            currentColumn = 0;
        }
    }

启动游戏后,显示GamePanel为灰色。当我垂直调整它的大小时,它突然出现了所有正确的值。我不明白为什么。我确实注意到调整大小会导致getValueAt被调用很多次。有人可以帮我理解这一点吗?

编辑2:如果我添加这一行:

        this.model.fireTableDataChanged();

增加,它似乎工作正常。我完全糊涂了……

编辑:这是我的 TableModel 类:

    private static class DataModel extends AbstractTableModel {

        private static final String[] names = {"White", "Black"};
        private final List<Row> values;

        public DataModel() {
            values = new ArrayList<Row>();
        }

        @Override
        public int getRowCount() {
            return values.size();
        }

        @Override
        public int getColumnCount() {
            return names.length;
        }

        @Override
        public Object getValueAt(int row, int col) {
            final Row currentRow = values.get(row);
            if(col == 0) {
                return currentRow.getWhiteMove();
            } else if (col == 1) {
                return currentRow.getBlackMove();
            }
            return null;
        }

        @Override
        public void setValueAt(Object aValue, int row, int col) {
            final Row currentRow;
            if(values.size() <= row) {
                currentRow = new Row();
                values.add(currentRow);
            } else {
                currentRow = values.get(row);
            }
            if(col == 0) {
                currentRow.setWhiteMove((Move) aValue);
            } else  if(col == 1) {
                currentRow.setBlackMove((Move)aValue);
            }
            this.fireTableCellUpdated(row, col);
        }

        @Override
        public Class<?> getColumnClass(int col) {
            return Move.class;
        }

        @Override
        public String getColumnName(int col) {
            return names[col];
        }
    }
}
4

2 回答 2

2

如果我将此行添加this.model.fireTableDataChanged()increment(),它似乎工作正常。

您的setValueAt()in实现DataMdel存在缺陷,因为它可能会Row向模型添加实例,而仅调用fireTableCellUpdated()单个rowand col。您需要触发适合实际修改的事件。

于 2012-12-14T10:52:03.337 回答
1

试着打电话

.invalidate();
.repaint();

在 JPanel、JScrollPane、JTable 上

我的猜测是添加作为最后几行increment()

JTable.invalidate();
JTable.repaint();

应该足够了。如果没有,请检查每个组件。

于 2012-12-14T05:17:00.340 回答