java - ScrollPane 内的 JTable 仅在调整大小后显示

标签 java swing jtable jscrollpane

我的应用程序的 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);
}

包含 JTable 的 JPanel 是“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];
        }
    }
}

最佳答案

If I add this line, this.model.fireTableDataChanged(), to increment(), it seems to work fine.

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

关于java - ScrollPane 内的 JTable 仅在调整大小后显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13873051/

相关文章:

java - 在 Java 中为自己的 IM 服务器/服务寻找简单的即时消息协议(protocol)

java - 如何让 JInternalFrame 填充容器并禁用拖动功能?

java - 如何改变JTable中行的颜色

java - JTable 中的可变行高;比在隐藏表模型列中存储高度值更好的方法?

用于过滤 jtable 行的 Java swing 切换按钮

java - 在 Java 中检查并从字符串中提取一个数字

java - 如何对暂停执行的代码进行单元测试而不将其抽象出来?

java - 如何制作一个包含单击时的 x 和 y 坐标的 ArrayList?

java - JWebBrowser(扩展 JPanel)显示在玻璃 Pane 上方

java - 选择行之前在 JTable 中执行操作