Странное поведение в fireTableDataChanged в JTable

До сих пор у меня было определение JTable, как это:

    JTable table = new JTable(model) {
        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component c = super.prepareRenderer(renderer, row, column);
            TradeTableModel model = (TradeTableModel) getModel();
            if ((Boolean) model.getValueAt(row, model.findColumn("Select"))) {
                Side s = (Side) model.getValueAt(row, model.findColumn("Side"));
                if (s == Side.BUY)
                    c.setBackground(Color.BLUE);
                else
                    c.setBackground(Color.red);
            }
            else {
                c.setBackground(Color.white);
            }
            return c;
        }
    };

Это должно было сделать так, чтобы строки меняли цвет в зависимости от выбора значения логического столбца. На мой AbstractTableModel Я указал метод установки значения следующим образом:

public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    assert columnIndex == 5;

    try{
        Selectable t = trades.get(rowIndex);
        t.setSelected((Boolean)aValue);
        fireTableDataChanged();
        //fireTableCellUpdated(rowIndex, columnIndex);
    }
    catch(Exception  e){
        throw new IllegalArgumentException("Object to set was not subtype of boolean");
    }

}

Если я использую fireTableDataChanged() цвет обновляется, когда я нажимаю флажок в графическом интерфейсе. Как бы то ни было, я действительно хочу отправить fireTableCellUpdated(rowIndex, columnIndex) поскольку другие обработчики должны знать местоположение ячейки. Однако в этом случае строка изменяется только в том случае, если я щелкаю по другой строке в таблице, как если бы она была отложена и ожидала какого-то другого события.

Любые идеи, почему это так?

2 ответа

Решение

Ваш (невидимый) TableModel должен fireTableXxxXxxx() как требуется для того, чтобы уведомить всех слушателей. DefaultTableModel делает это автоматически; AbstractTableModel должен сделать это в setValueAt(), Одним из таких слушателей является сама таблица. Если "другие обработчики должны знать местоположение ячейки", они могут зарегистрироваться для TableModelEvent экземпляры через addTableModelListener(), Они также могут прислушиваться к выбору пользователя по мере необходимости.

  • должны уведомить правильный метод, fireTableCellUpdated(row, col);

  • больше о AbstractTableModel и prepareRenderer и его методах, пожалуйста, прочитайте комментарий @camickr

  • посмотреть на convertXxxToModel в том случае, если JTable фильтруется или сортируется, например

Другие вопросы по тегам