TableHeaderRenderer с Nimbus

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

Проблема, с которой я сталкиваюсь, связана с меткой, возвращаемой средством визуализации по умолчанию. Вызов средства визуализации по умолчанию предоставляет стандартную метку. Если я верну это как есть, оно будет выглядеть так, как ожидалось. Если я попытаюсь изменить фон или границу, ничего не изменится. Однако изменение переднего плана имеет ожидаемый эффект. Я не хочу просматривать значки сортировки, поэтому я пытаюсь создать JLabel, который выглядит так же, за исключением значков. Это тоже работает не корректно. Мой JLabel непрозрачен.

JLabel l = (JLabel)table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
this.lbl.setBackground(l.getBackground());
return this.lbl;

Я просмотрел исходный код DefaultTableHeaderRenderer и не нашел ничего особенного в том, что делает класс по умолчанию.

Я также пробовал следующее без эффекта.

this.lbl.setOpaque(true);
this.lbl.setFont(UIManager.getFont("TableHeader.font"));
this.lbl.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
this.lbl.setBackground(UIManager.getColor("TableHeader.background"));
this.lbl.setForeground(UIManager.getColor("TableHeader.foreground"));
return this.lbl;

РЕДАКТИРОВАТЬ: Уточнение. Оба приведенных выше фрагмента кода находятся внутри getTableCellRenderComponent() моего пользовательского средства визуализации. Я пробовал оба способа, и ни один из них не работал.


person Dodd10x    schedule 12.04.2013    source источник
comment
Вы не должны пытаться изменить заголовок вне процесса его рендеринга. Вместо этого вы должны предоставить свою собственную реализацию TableCellRenderer, которая обеспечивает требуемую функциональность, и установить для нее JTableHeader   -  person MadProgrammer    schedule 12.04.2013
comment
Отредактировано для уточнения. Я делаю это внутри пользовательской реализации TableCellEditor.   -  person Dodd10x    schedule 12.04.2013
comment
Тогда зачем ты делаешь table.getTableHeader().getDefaultRenderer()?   -  person MadProgrammer    schedule 12.04.2013
comment
Я пытался получить метку по умолчанию для текущего внешнего вида, чтобы получить его свойства, такие как фон и граница, для использования в моем собственном компоненте. Это не работает, как я ожидал.   -  person Dodd10x    schedule 12.04.2013


Ответы (1)


Попробуйте использовать значения UIManagers напрямую.

TableHeader.background = DerivedColor(color=214,217,223 parent=control offsets=0.0,0.0,0.0,0 pColor=214,217,223
TableHeader.font = javax.swing.plaf.FontUIResource[family=SansSerif,name=sansserif,style=plain,size=12]
TableHeader.foreground = DerivedColor(color=0,0,0 parent=text offsets=0.0,0.0,0.0,0 pColor=0,0,0
TableHeader.opaque = true

Что-то вроде UIManager.getColor("TableHeader.background") например

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

Обновлено с примером

введите здесь описание изображения

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

Второй столбец — это средство визуализации по умолчанию, а третий — дерзкий. По сути, это кража рендерера ячеек прямо из заголовка таблицы...

package testcellrenderer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class TestCellRenderer {

    public static void main(String[] args) {
        new TestCellRenderer();
    }

    public TestCellRenderer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            DefaultTableModel model = new DefaultTableModel(
                            new Object[][]{{"Testing", "Testing", "Testing"}},
                            new Object[]{"Test A", "Test B", "Test C"}
                            );
            JTable table = new JTable(model);
            table.getColumn("Test A").setCellRenderer(new TestTableCellRenderer());
            table.getColumn("Test C").setCellRenderer(table.getTableHeader().getDefaultRenderer());

            setLayout(new BorderLayout());
            add(new JScrollPane(table));
        }

    }

    protected class TestTableCellRenderer extends DefaultTableCellRenderer {

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

            Color background = UIManager.getColor("TableHeader.background");
            Color foreground = UIManager.getColor("TableHeader.foreground");
            Font font = UIManager.getFont("TableHeader.font");
            boolean opaque = UIManager.getBoolean("TableHeader.opaque");

            setBackground(background);
            setForeground(foreground);
            setFont(font);
            setOpaque(opaque);

            return this;
        }       
    }   
}
person MadProgrammer    schedule 12.04.2013
comment
Концепция рендереров работает для Nimbus без ограничений, но не для JTableHeader, лично никогда не пробовал, один из кодов @kleopatra (опять же в power_save_mode) - person mKorbel; 12.04.2013
comment
@MadProgrammer Как бы то ни было (опоздал к этому разговору), но я не могу заставить фон ячеек заголовка рисовать с помощью схемы градиентных цветов. У меня есть собственный рендерер, который использует код класса DefaultTableCellHeaderRenderer (скопируйте/вставьте для проверки), и я добавляю этот рендерер в качестве средства рендеринга заголовков по умолчанию в свою таблицу, и происходит то, что граница не рисуется (если только у меня не было моего собственный вызов setBorder в моем рендерере), а фон ячеек заголовков столбцов окрашен плоско, а не градиентом. - person Adrian Romanelli; 08.03.2016
comment
@MadProgrammer --laf com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel - person Adrian Romanelli; 09.03.2016
comment
@AdrianRomanelli Вы пытаетесь изменить средство визуализации для ячейки или заголовка? Как я уже говорил в ответе, кажется, что граница нарисована самим делегатом l&f - person MadProgrammer; 09.03.2016
comment
@MadProgrammer Единственное изменение, которое я делаю в своем средстве визуализации, — это изменение значка для сортировки для каждой ячейки заголовка столбца, а не для ячеек тела таблицы (мы разрешаем фильтрацию и показываем отдельный значок для отфильтрованного столбца). Что касается границы, как я уже упоминал ранее, граница вообще не рисуется, если только я сам явно не рисую ее. Кроме того, цвет фона — это не градиентный цвет, а простой/плоский цвет, в отличие от других таблиц, которые не используют мой заголовок таблицы. - person Adrian Romanelli; 09.03.2016