Странное поведение на 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), так как другим обработчикам нужно знать местоположение ячейки. Однако в этом сценарии строка изменяется только в том случае, если я нажимаю на другую строку в таблице, как если бы она была отложена и ждала какого-то другого события.

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


person Bober02    schedule 02.08.2012    source источник
comment
fireXX должен включать все значения модели, на которые может повлиять setValueAt(..). В зависимости от точного контекста должно запускаться несколько более широкое событие: f.i. если какое-то условие где-то еще в строке затронуто, запустите tableRowUpdate. Или, если могут быть затронуты некоторые другие строки, запустите tableRowsUpdated(0, getRowCount())   -  person kleopatra    schedule 03.08.2012
comment
ЕСЛИ вы хотите использовать fireTableCellUpdated, я бы посоветовал вам запустить два события. Я первый должен уведомить, что СТАРАЯ выбранная ячейка изменилась, а второй должен уведомить, что НОВАЯ выбранная ячейка изменилась. Здесь важно помнить, что процесс рисования JTable очень оптимизирован, поэтому вызов cellUpdated обычно обновляет только эту ячейку и не влияет на другие ячейки.   -  person MadProgrammer    schedule 03.08.2012
comment
Я решил запустить два события: одно для строки, чтобы изменить ее краску, а затем событие обновления ячейки для дальнейшей обработки этой конкретной ячейки.   -  person Bober02    schedule 03.08.2012


Ответы (2)


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

person trashgod    schedule 02.08.2012

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

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

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

person mKorbel    schedule 02.08.2012
comment
Итак, мне нужно просто перерисовать и перепроверить таблицу, чтобы вызвать perpareRenderer? - person Bober02; 02.08.2012
comment
не эта работа выполняется по умолчанию prepareRenderer, вы пытались redirect / change значение для prepareRenderer с Boolean value на другое column, а Id предложить обернуть Цвет или форматирование в if (table.getRows > 0) для защиты от XxxException... - person mKorbel; 02.08.2012