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

Если вы хотите добавить собственный рендерер, обычно вы либо расширяете некоторые JComponent (например, JLabel) и реализуете TableCellRenderer, либо расширяете DefaultTableCellRenderer. Однако в любом случае я обнаружил, что стиль ячейки полностью переопределен.

Что бы я действительно хотел, так это иметь возможность рисовать фон L&F по умолчанию, а затем рисовать поверх него, используя другие значения по умолчанию L&F, такие как цвет переднего плана и шрифт.

Итак, вот что я пытался сделать. Во-первых, класс:

public class IntervalHeaderRenderer extends JLabel implements TableCellRenderer {

    private TableCellRenderer delegate;
    private Component component;

    public IntervalHeaderRenderer(TableCellRenderer defaultRenderer)
    {
        this.delegate = defaultRenderer;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
                           boolean isSelected, boolean hasFocus, int row, int column)
    {
        component = delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        // Maybe override some settings.  
        // You could make the label bold, for instance.

        return component;
        // return this;
    }

    @Override
    public void paint(Graphics g) {
        // What I really want to do is paint the original component
        component.paint(g);
        // And then draw on top of it.
    }
}

И затем я переопределяю средство визуализации ячейки (заголовка) следующим образом:

TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
table.getColumnModel().getColumn(1).setHeaderRenderer(new IntervalHeaderRenderer(renderer));

В основном я просто следую приведенным здесь предложениям: TableCellRenderer, часть 2. Как создать собственный модуль визуализации< /а>

Если я верну component, это будет выглядеть так, как будто я ничего не переопределил. То есть я получаю заголовок с запрограммированной меткой с выбранным фоном и стилем L&F и все такое. Но, конечно же, после этого невозможно отрендерить мой материал.

С другой стороны, если я верну this, то я абсолютно ничего не получу. Родной для Mac L&F дает мне белый фон, в то время как Nimbus дает мне сплошной цвет другого цвета.

Я явно что-то упускаю. Есть ли другие методы на Component, которые мне нужно переопределить и перенаправить на оригинал? Как отрисовывается компонент по умолчанию, если не переопределением paint? (Я также пытался переопределить paintComponent. Без разницы.)

Есть ли другой способ сделать это? Я думал о том, чтобы попытаться поместить туда собственный стиль JPanel, а затем сделать пользовательский (прозрачный фон) компонент своим дочерним элементом, хотя я не уверен, как это сделать, и я не совсем уверен, что я бы в любом случае получить собственный фон header таблицы L&F. На самом деле, я очень сомневаюсь, что получу родной стиль заголовка, только родной стиль JPanel.

По сути, мне нужен собственный заголовок таблицы (и отдельно ячейки, на самом деле), но я хочу не слишком возиться с родным L&F.

Спасибо!


person Timothy Miller    schedule 19.09.2011    source источник
comment
нарисуйте фон L&F по умолчанию, а затем нарисуйте поверх него, используя другие значения L&F по умолчанию, такие как цвет переднего плана и шрифт. - если все должно быть по умолчанию, просто используйте .. по умолчанию ;-) Поскольку это не может быть вашим намерением: что точно вы хотите отличаться от значения по умолчанию?   -  person kleopatra    schedule 19.09.2011


Ответы (2)


Вы можете посмотреть на подход, использованный в updateUI(), в SelectAllHeaderTest, а также полезные оговорки в принятом ответе.

Приложение: В качестве пояснения обратите внимание, что внешний вид заголовка находится под эгидой соответствующего делегата пользовательского интерфейса хост-платформы, обычно производного от TableHeaderUI. Вы можете ограничить свои изменения значениями UIManager по умолчанию общий для популярных реализаций Look & Feel. Кроме того, не переопределяйте paint(). Я бы не стал переопределять paintComponent(); и, при необходимости, переопределите paintIcon(), как показано в TableSorter.

person trashgod    schedule 19.09.2011
comment
Спасибо за помощь! Я почти там. Основываясь на вашем предложении, теперь у меня есть правильный фон. Однако вы говорите не переопределять paint(). Что вместо этого мне нужно переопределить, чтобы нарисовать свой собственный виджет поверх фона? Спасибо. - person Timothy Miller; 19.09.2011
comment
На самом деле, используя этот метод, он подходит для Mac, но не для Nimbus. - person Timothy Miller; 19.09.2011
comment
Программы Swing должны переопределять paintComponent(), а не paint(). — Рисование в AWT и свинг. Предоставьте sscce, показывающий ваш пересмотренный подход. - person trashgod; 19.09.2011

Проверьте исходный код DefaultTableCellRenderer, там вы увидите, как поведение по умолчанию считывает цвета по умолчанию, например:

        fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
        bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
person Daniel De León    schedule 11.04.2013