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);
}

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サイズを変更すると、何度も呼び出されることに気付きました。誰かがこれを理解するのを手伝ってくれますか?

EDIT 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の実装には、単一のandを呼び出すだけで、 のDataMdelインスタンスをモデルに追加する可能性があるという点で欠陥があります。実際の変更に適したイベントを発生させる必要があります。RowfireTableCellUpdated()rowcol

于 2012-12-14T10:52:03.337 に答える
1

電話してみる

.invalidate();
.repaint();

JPanel、JScrollPane、JTable のいずれか

私の推測では、最後の行として追加することですincrement()

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

十分なはずです。そうでない場合は、各コンポーネントを確認してください。

于 2012-12-14T05:17:00.340 に答える