Вызвать prepareRenderer JTable Swing

Имейте мою реализацию JTable с модификацией prepareRenderer.

public class MyTable extends JTable {

    private List<Client> list;

    public MyTable(TableModel model){
        super(model);
        if (model instanceof ProfitAbilityTableModel){
            list=((ProfitAbilityTableModel)model).getClients();
        }       
    }
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex){
        Component rComp=super.prepareRenderer(renderer, rowIndex, vColIndex);
        if(list!=null){
            Client client=list.get(rowIndex);
            if(client.getExpected()==client.getReceived())
                rComp.setBackground(new Color(139, 255, 182));
            else
                rComp.setBackground(new Color(255,139,147));
        }

        return rComp;
    }
}

ProfitAbilityTableModel

public class ProfitAbilityTableModel  extends AbstractTableModel{

    private String []columnNames={"Имя учетной записи", "Ф.И.О. Клиента","Адрес",
            "Получено грн.", "Предпологалось грн."};
    private List<Client> clients;

    public ProfitAbilityTableModel(List<Client> clients){
        this.clients=clients;
    }

    public ProfitAbilityTableModel(){};

    @Override
    public int getColumnCount() {
        return 5;
    }

    @Override
    public int getRowCount() {
        return (clients!=null) ? clients.size(): 0;
    }

    @Override
    public Object getValueAt(int r, int c) {
        Client client=clients.get(r);
        switch (c) {
            case 0:
                return client.getUserName();
            case 1:
                return client.getName() +" " + client.getSurname() + " " + client.getPatronymic();
            case 2:
                return client.getAddress();
            case 3:
                return client.getReceived();
            case 4:
                return client.getExpected();    
            default:
                return null;
        }
    }

    @Override
    public String getColumnName(int c){
        return columnNames[c];
    }

    public List<Client> getClients() {
        return clients;
    }


}

В mainFrame создайте таблицу с пустой таблицей tableModel = new MyTable(new ProfitAbilityTableModel());

когда нажимаешь кнопку делай так

button_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                table.setModel(new ProfitAbilityTableModel(ClientFactory.getClients(10)));
            }
        });

где КлиентФабрика:

public class ClientFactory {
    public static List<Client> getClients(int amount){
        List<Client> result=new ArrayList<>();
        Client c;
        int received,expected;
        for(int i=0;i<amount;i++){
            c=new Client();
            c.setUserName("username " + i);
            c.setName("name "+ i);
            c.setSurname("surname " + i);
            c.setPatronymic("patronymic" + i);
            c.setAddress("address " + i);
            expected=(int)(Math.random()*100);
            received=(int)(Math.random()*100);
            if(received>expected)
                received=expected;
            c.setExpected(expected);
            c.setReceived(received);
            result.add(c);
        }
        return result;
    }
}

Сделано это для изменения цвета строки, если два поля Client равны. При создании MyTable все работает нормально, но при изменении tableModel все строки имеют цвет фона по умолчанию (белый). Как вызвать этот код при изменении модели таблицы?


person disable1992    schedule 16.04.2014    source источник
comment
Да, при нажатии кнопки программа устанавливает новую модель таблицы с новыми данными. Это сложно. В будущем нужно будет брать данные из БД.   -  person disable1992    schedule 16.04.2014
comment
Может я иду не тем путем? Так подсказал мне, как реализовать это правильно.   -  person disable1992    schedule 16.04.2014
comment
1. set new table model with new data. It's tricky. - не вижу в этом никакого преимущества, JTable и его XxxTableModel предназначены для повторного использования, 2. нужно посмотреть (лучший код и простая, понятная логика внутри...) блог @camickr XxxTableModel и prepareRenderer большая часть кода, о котором идет речь, это только копипаста из этого блога, 3. In future it's take data from DB тоже ищите здесь таблицу из базы данных   -  person mKorbel    schedule 16.04.2014
comment
1. преобразовать индекс в модель, затем проверить значение в модели из столбца 6 (if(client.getExpected()==client.getReceived()) сделать меня ерундой, этот элемент должен возвращать реальное значение - String, Integer, Boolean), 2. удалить рекрутивное тестирование для if(list!=null){ должно быть model isn't mull, лучше проверить, больше ли количество строк в модели 0 (должно быть для prepareRenderer по умолчанию)   -  person mKorbel    schedule 16.04.2014


Ответы (1)


Проблема решается добавлением в ProfitAbilityTableModel следующих методов:

public void setData(List<Client> clients){
        this.clients=clients;
    }

    public Client getClient(int index){
        return clients.get(index);
    }

Изменить мою таблицу:

public class MyTable extends JTable {

    public MyTable(TableModel model){
        super(model);   
    }
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex){
        Component rComp=super.prepareRenderer(renderer, rowIndex, vColIndex);
        if(getModel()!=null){
            Client client=((ProfitAbilityTableModel)getModel()).getClient(rowIndex);
            if(client.getExpected()==client.getReceived())
                rComp.setBackground(new Color(139, 255, 182));
            else
                rComp.setBackground(new Color(255,139,147));
        }

        return rComp;
    }
}

В основном фрейме обновите данные с помощью такой кнопки:

ProfitAbilityTableModel model=(ProfitAbilityTableModel)table.getModel();
model.setData(ClientFactory.getClients(10));
model.fireTableDataChanged();
person disable1992    schedule 16.04.2014
comment
опубликовать SSCCE / MCVE / MCTRE, короткий, работоспособный, компилируемый с жестко закодированным значением для JTable / XxxTableModel, хранящимся в локальной переменной, никогда не вызывать model.fireXxxXxx из класса моделей, снова ваша модель не завершена, это путь к беды, код для JTable, его модели и рендерера очень простая работа, перестаньте усложнять простые вещи и неправильно - person mKorbel; 16.04.2014