Средство визуализации ячеек JTable, установленное на фоне других ячеек - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть JTable с пользовательским cell renderer, чтобы выделить ячейку, если есть новая глава в сети.

DefaultTableCellRenderer:

static class CustomRenderer extends DefaultTableCellRenderer {

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        double valueAt = (double) table.getValueAt(row, column);
        double compareValue = (double) table.getValueAt(row, column - 1);
        if (compareValue < valueAt) {
            cellComponent.setBackground(Color.green);
        } else {
            Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
            // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
            // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
            Color background = tableCellRendererComponent.getBackground();
            cellComponent.setBackground(background);
        }

        return cellComponent;
    }
}

Настольная модель:

private String[] columnsGetNewest = {"Current Chapter", "Chapter Online"};
private DefaultTableModel dataModelGetNewest = new DefaultTableModel(columnsGetNewest, 0);

Применяется с использованием:

tableGetNewest.setModel(dataModelGetNewest);
TableColumn column = tableGetNewest.getColumnModel().getColumn(1);
column.setCellRenderer(new CustomRenderer());

Желаемый результат:

enter image description here

Но по какой-то причине он не работает должным образом:

enter image description here

Код работаеткак это происходит в ветке else.

Если я закомментирую //cellComponent.setBackground(Color.green); результат будет выглядеть так:

enter image description here

В чем проблемас моим кодом?Как я могу получить желаемый результат?

1 Ответ

1 голос
/ 20 сентября 2019

Если я правильно понял, вы пытаетесь повернуть Green все ячейки в правом столбце, которые имеют более высокое значение, чем ячейки в левом столбце.Поправьте, если я ошибаюсь.

Проблема на вашем TableCellRenderer.В следующей части:

if (compareValue < valueAt) {
    cellComponent.setBackground(Color.green);
} else {
    Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
    // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
    // Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
    Color background = tableCellRendererComponent.getBackground();
    cellComponent.setBackground(background);
}

Я думаю, что лучший способ объяснить вам, что вы сделали не так, это на примере.Скажем, правое значение больше левого значения в левом столбце, поэтому ваш if имеет место, а фон renderer превращается green.Теперь давайте отрендерим строку 2. Правое значение меньше левого, поэтому if не имеет места.Угадай, что?Вы сделали это зеленым в предыдущей строке рендера, поэтому он остается green.Вот почему они остаются зелеными.Если вы включите его один раз и не восстановите его, он останется для остальных из них.

Теперь, когда вы попытаетесь восстановить фон, вы super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);.Это неправильно, поскольку этот метод не является простым методом получения.Также вносит изменения в таблицу (рендереры).Вызов этого метода для других значений строки / столбца не будет работать.

Чтобы сделать это, вам нужно будет восстановить его в соответствии со значением по умолчанию, полученным из DefaultTableCellRenderer.Полный пример:

public class Example extends JFrame {
    private static final long serialVersionUID = 811854316682851407L;
    private static final String[] COLUMNS = { "Current Chapter", "Chapter Online" };

    public Example() {
        super("test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JTable table = new JTable(data(), COLUMNS);
        table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
                    int column) {
                Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (c instanceof JLabel) {
                    JLabel renderer = (JLabel) c;
                    int valueAt = (int) table.getValueAt(row, column);
                    int compareValue = (int) table.getValueAt(row, column - 1);
                    if (compareValue < valueAt) {
                        renderer.setBackground(Color.GREEN);
                    } else {
                        if (isSelected)
                            renderer.setBackground(table.getSelectionBackground());
                        else {
                            renderer.setBackground(table.getBackground());
                        }
                    }
                }
                return c;
            }
        });
        JScrollPane sp = new JScrollPane(table);
        add(sp);
        pack();
        setLocationRelativeTo(null);
    }

    private Object[][] data() {
        Object[][] data = { { 113, 444 }, { 233, 555 }, { 110, 92 }, { 55, 66 }, { 123, 603 }, { 412, 120 }, };
        return data;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Example().setVisible(true));
    }
}

Предварительный просмотр:

preview

...