Переопределение DefaultTableCellRenderer JTable для центрирования всех ячеек в JTable

У меня есть проблема, от которой я не могу избавиться.

Просто чтобы вы знали, я новичок в использовании JTables, поэтому ответ может быть простым, но я не могу найти решение:/

Итак, у меня есть JTable, использующий AbstractTableModel, который переопределяет

    public Class<?> getColumnClass(int columnIndex_p) 

метод, чтобы указать тип каждого отображаемого столбца. Один из них булев.

Когда я создаю простой JTable, используя

    table_l = new JTable(new MyTableModel());

все нормально, булевы значения корректно отображаются с помощью флажков (вкл/выкл).

Теперь я хотел бы центрировать текст в каждой ячейке (и, возможно, больше вариантов позже).

Поэтому я определяю новый DefaultTableCellRenderer для каждого столбца, например:

    DefaultTableCellRenderer cellRenderer_l = new DefaultTableCellRenderer() {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          // delegate the rendering part to the default renderer (am i right ???)
          Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
          return comp;
        }
    }

а затем я просто устанавливаю горизонтальное выравнивание этого CellRender с помощью:

    cellRenderer_l.setHorizontalAlignment(JLabel.CENTER);

Затем я устанавливаю этот новый CellRenderer в каждый столбец JTable:

    for (int i = 0; i < table_l.getColumnCount(); ++i) {
        table_l.getColumnModel().getColumn(i).setCellRenderer(cellRenderer_l);
    }

Но с новым CellRenderer отображаемый JTable больше не использует метод getColumnClass() моей TableModel и, таким образом, просто отображает строку «true/false» для логических значений.

Я не знаю, как заставить его по-прежнему использовать getColumnClass(), как раньше.

Если у кого-то есть ответ... Спасибо

РЕДАКТИРОВАТЬ: спасибо за все разъяснения, которые вы сделали. Фактически, мой настоящий вопрос был: «Как повлиять на все DefaultRenderer JTable, чтобы они центрировали свой результат в ячейках JTable»


person adrien.pain    schedule 08.02.2013    source источник
comment
Проверь это. Вы можете получить подсказку. Здесь я предложил добавить радиокнопки в столбец таблицы. - stackoverflow.com/questions/9117716/   -  person Ravindra Gullapalli    schedule 08.02.2013
comment
Спасибо за быстрый ответ. Однако неужели нет более простого решения? На самом деле все, что я хочу сделать, это определить новый DefaultCellRenderer, который работает точно так же, как по умолчанию, используемый JTable, но просто центрирует текст в ячейках.   -  person adrien.pain    schedule 08.02.2013
comment
если установлены средства визуализации для каждого столбца, они используются независимо от значений по умолчанию для каждого класса (см. источник JTable для точной логики поиска)   -  person kleopatra    schedule 08.02.2013
comment
@kleopatra спасибо за ваш ответ, я не знал об этом. Затем я попытался переопределить DefaultCellRenderer для Object, Number и Boolean и вызвать setHorizontalAlignment(CENTER) этих новых DefaultCellRenderer, но безуспешно.   -  person adrien.pain    schedule 08.02.2013


Ответы (2)


Для применения одного и того же визуального оформления ко всем компонентам рендеринга (если это то, чего вы действительно хотите, будьте осторожны, это может привести к снижению удобства использования!) вы можете переопределить метод подготовленного Renderer JTable:

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(...);
    if (comp instanceof JLabel) {
        ((JLabel) comp).setHorizontalAlignment(...);
    }
    return comp;
}

Кстати: этот подход нарушает правило не подкласса JSomething для нужд приложения. Вы можете использовать SwingX, который формально поддерживает визуальное оформление компонентов рендеринга. Таким образом, вместо создания подкласса вы должны зарегистрировать Highlighter в таблице:

JXTable table = ...
table.addHighlighter(new AlignmentHighlighter(CENTER), HighlightPredicate.ALWAYS);   
person kleopatra    schedule 08.02.2013
comment
спасибо за пример JXTable. Я обновил свой проект, поэтому теперь использую только JXTables. Он получил хороший API высокого уровня и идеально подходит для моих нужд. Еще раз спасибо ! - person adrien.pain; 08.02.2013

Ячейка по умолчанию рендерер уже делает это для значений введите Boolean.class, как показано здесь. Если этого недостаточно, отредактируйте свой вопрос, включив в него sscce, в котором указаны все проблемы, с которыми вы столкнулись.

Приложение. Если вам нужно дополнительно настроить DefaultTableCellRenderer, укажите средство визуализации для применимого типа с помощью setDefaultRenderer(), как показано здесь.

table.setDefaultRenderer(Boolean.class, yourCellRenderer); 

изображение

person trashgod    schedule 08.02.2013
comment
да, я знаю, что средство визуализации по умолчанию обрабатывает логические значения как флажки. На самом деле все, что я хочу сделать, это определить новый DefaultCellRenderer, который работает точно так же, как по умолчанию, используемый JTable, но просто центрирует текст в ячейках. - person adrien.pain; 08.02.2013
comment
Я думаю, вы хотите применить средство визуализации по классам, а не по столбцам; больше выше. - person trashgod; 08.02.2013
comment
спасибо за подсказку. Я мог бы определить множество рендереров, по одному для каждого возможного типа в моих JTables, а затем настроить их. Но я хотел бы сказать JTable: просто используйте свой рендерер по умолчанию, но центрируйте результат в ячейке. Разве нет простого способа сделать это? :( - person adrien.pain; 08.02.2013
comment
Я думаю, что CENTER используется по умолчанию как для DefaultTableCellRenderer, так и для DefaultCellEditor(JCheckBox). Вы видите что-то другое? - person trashgod; 08.02.2013
comment
CENTER используется по умолчанию для JCheckBox, но String выравниваются по левому краю, а Numbers выравниваются по правому краю. Я хочу, чтобы мой JTable центрировал содержимое каждой ячейки, не учитывая ее тип. - person adrien.pain; 08.02.2013
comment
Но, увидев ваши ответы и документацию, я начинаю думать, что мне придется заменить средство визуализации для всех возможных типов в моем JTable, которые я хочу центрировать. Например, установка новых рендереров для String, новых рендереров для чисел и т. д. - person adrien.pain; 08.02.2013
comment
придирка: средство визуализации по умолчанию для логических значений не имеет тип DefaultTableCellRenderer, а Center не является выравниванием по умолчанию для DefaultTableCellRenderer:-) +1 за то, что вы действительно имеете в виду - person kleopatra; 08.02.2013
comment
@adrien.pain Я сомневаюсь, что вы (читай: ваши пользователи) действительно хотите, чтобы числа были центрированы :-) В любом случае, вы, вероятно, захотите отредактировать свой вопрос и добавить туда пояснение - person kleopatra; 08.02.2013
comment
@kleopatra подчеркивает важное различие: JTable средства визуализации по умолчанию также реализуют UIResource и вызывают setHorizontalAlignment() как задокументировано. Если вы действительно хотите изменить выравнивание по умолчанию, вы обычно можете заменить средство визуализации по умолчанию на производное от DefaultTableCellRenderer. - person trashgod; 08.02.2013
comment
@trashgod да, я хочу выбрать выравнивание по умолчанию, заменив средство визуализации по умолчанию. Но как просто сделать это, пожалуйста? - person adrien.pain; 08.02.2013
comment
ответ @kleopatra является диспозитивным; не стесняйтесь принять этот ответ, но, пожалуйста, обновите свой вопрос, чтобы отразить намерение повлиять на все средства визуализации. - person trashgod; 08.02.2013
comment
@kleopatra спасибо за ваш ответ. Я приму ваш ответ как правильный ответ, который я искал - person adrien.pain; 08.02.2013