Использование intercellSpacing в JTable с пользовательским цветом фона строки приводит к неожиданным результатам - PullRequest
3 голосов
/ 08 ноября 2010

У меня есть JTable, где я хочу выделить несколько строк, используя собственный цвет фона. Это я сделал со следующим классом:

public class MyTable extends JTable {

    private List<RefData> data = null;

    public List<RefData> getData() {
        return data;
    }

    public void setData(List<RefData> data) {
        this.data = data;
    }

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(renderer, row, column);

        if (this.data == null || row < 0 || row > this.data.size()-1){
            return comp;
        }

        RefData rowData = this.data.get(row);
        if (rowData.getStatus() < 3000){
            comp.setBackground(Color.YELLOW);
        } else {
            comp.setBackground(Color.WHITE);
        }

        return comp;
    }

}

Все это работает как шарм, и я получаю именно то, что хочу. Затем, глядя на полученный графический интерфейс, я понимаю, что таблица выглядит слишком сжатой. Все выглядит сжато вместе. Как всегда с настройками JTable по умолчанию;)

Ну, это легко решить, я подумал:

myTable.setIntercellSpacing(new java.awt.Dimension(10, 1));

Теперь ячейки хорошо расположены , но , добавленные поля ячеек теперь имеют цвет фона таблицы по умолчанию, который в моем случае белый. Это выглядит ужасно.

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

Мое prepareRenderer решение не подходит для этой задачи? Или есть другое решение?

Ответы [ 3 ]

3 голосов
/ 08 ноября 2010

Граничный подход верен, но лучше сделать это с помощью средства визуализации ячеек, а не prepareRenderer() метода:

    JTable.setDefaultRenderer(Object.class, new DefaultCellRenderer() {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            JComponent component = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            component.setBorder(...);
            return component;
        }
    });
3 голосов
/ 08 ноября 2010

Может кто-нибудь подтвердить, что это правильный путь в Swing?

Переопределение prepareRenderer() имеет преимущество применения ко всем ячейкам, и «внутренние реализации всегда используют этот метод для подготовки средств визуализации, чтобы это поведение по умолчанию можно было безопасно переопределить подклассом». Я не вижу проблемы, даже если позже вы используете setDefaultRenderer() для определенного класса.

Приложение: Примеры можно найти в статье Рендеринг таблицы строк и связанный с этим ответ .

1 голос
/ 08 ноября 2010

Я сейчас придумал следующее решение. Мне кажется, все в порядке. Но кто-то может подтвердить, что это правильный (или правильный способ) сделать это в крыле, пожалуйста?

public class MyTable extends JTable {

    // [snip]

    private Border paddingBorder = BorderFactory.createEmptyBorder(2, 3, 2, 3);

    // [snip]

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(renderer, row, column);

        if (JComponent.class.isInstance(comp)){
            ((JComponent)comp).setBorder(paddingBorder);
        }

        // [snip]
    }

    // [snip]

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...