По моему опыту, лучше получить DefaultTableCellHeaderRenderer
при перезаписи любого JTable
Renderer
. Таким образом, вместо того, чтобы связываться с JLabel
из Renderer
напрямую, вы берете Renderer
с super()
. Итак, ваш код должен выглядеть так:
header.setDefaultRenderer(new DefaultTableCellHeaderRenderer() {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellHeaderRenderer rendererComponent = (DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (selectedColumn == value) {
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createLineBorder(Color.red, 1)));
rendererComponent.setHorizontalAlignment(SwingConstants.LEFT);
} else {
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0)));
rendererComponent.setHorizontalAlignment(SwingConstants.CENTER);
}
if (column == 0) {
rendererComponent.setForeground(Color.red);
} else {
rendererComponent.setForeground(header.getForeground());
}
return rendererComponent;
}
});
Чтобы попытаться ответить на ваши вопросы напрямую:
Вопрос 1:
В: Как правильно использовать средства визуализации клиентов для рисования определенных ячеек в JTable?
A: Ваш текущий код устанавливает Renderer
на JTableHeader
. Чтобы добавить Renderer в ячейки таблицы, код будет аналогичен приведенному выше, только вы зададите его с помощью модели Column:
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// Set your code to render your component.
return renderer;
}
});
Примечание по этому поводу: JTables
основаны на столбцах, что означает, что все данные в определенном столбце должны быть одного типа (ваш SSCCE следует этому соглашению). Мое любимое занятие - предоставить пользовательский Renderer
для каждого типа. Например, когда у меня есть столбец Date
, я использую этот рендерер:
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import org.joda.time.LocalDate;
/**
*
* @author Ryan
*/
public class DateCellRenderer extends DefaultTableCellRenderer {
String pattern;
public DateCellRenderer(String pattern){
this.pattern = pattern;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value != null && value instanceof LocalDate) {
renderer.setText(((LocalDate)value).toString(pattern));
} else
throw new IllegalArgumentException("Only supported Object type is LocalDate.");
return renderer;
}
}
И я называю этот код чем-то похожим:
table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy"));
Вопрос 2:
Q: определенный цвет заголовка таблицы java swing
A: Ммм ... Кажется, ваш SSCCE понял это.
Вопрос 3:
Q: о super.getTableCellRendererComponent (...) должна быть последняя строка кода перед возвратом, я не могу написать правильный Renderer по этим советам, для меня работает только так
A: Я не уверен, что вы имеете в виду "должна быть последняя строка кода перед возвратом". Это не тот случай, что подтверждается приведенным выше фрагментом кода
Вопрос 4:
Q: JLabel добавлен для Borders, HorizontalAlignment и Foreground, особенно Background заставил меня несколько non_senses при использовании Component вместо JLabel, (здесь как-то не важно)
A: Хорошо ... DefaultTableCellHeaderRenderer
достаточно для всех этих границ, выравнивания, переднего и заднего плана.