Почему средства визуализации ячеек часто расширяют JLabel?

Я заметил, что это обычное дело. Например, его используют DefaultListCellRenderer, DefaultTableCellRenderer и DefaultTreeCellRenderer. Кроме того, многие пользовательские рендереры ячеек, которые я вижу в Интернете, также используют это. Я хочу использовать собственный TableCellRenderer в своем коде, но я не уверен, действительно ли мне нужно создать подкласс JLabel. В чем преимущество подкласса JLabel?


person Eva    schedule 06.10.2011    source источник


Ответы (3)


В API для DefaultTableCellRenderer указано:

Класс таблицы определяет средство визуализации одной ячейки и использует его в качестве штампа для визуализации всех ячеек в таблице; он отображает первую ячейку, изменяет содержимое средства визуализации этой ячейки, сдвигает начало координат в новое место, перерисовывает ее и т. д. Стандартный компонент JLabel не предназначен для использования таким образом, и мы хотим избежать запуска revalidate каждый раз, когда ячейка рисуется. Это значительно снизит производительность, поскольку сообщение revalidate будет передано вверх по иерархии контейнера, чтобы определить, будут ли затронуты какие-либо другие компоненты. Поскольку рендерер создается только на время жизни операции рисования, мы также хотим избежать накладных расходов, связанных с прохождением иерархии для операций рисования. Таким образом, этот класс переопределяет методы validate, invalidate, revalidate, repaint и firePropertyChange, чтобы они были неоперативными, и переопределяет метод isOpaque исключительно для повышения производительности. Если вы пишете свой собственный рендерер, помните об этом соображении производительности.

person camickr    schedule 06.10.2011
comment
@Eva: Я предлагаю вам снять отметку с моего ответа и переключить проверку ответа на сообщение camickr. Это прямо по деньгам. - person Hovercraft Full Of Eels; 06.10.2011
comment
лично я ни во что из этого не верю. Это происходит из-за высокой паранойи производительности (хотя SwingX имеет пользовательские компоненты рендеринга, которые делают переопределяют эти методы, чтобы чувствовать себя в безопасности ;-) - person kleopatra; 06.10.2011

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

person Hovercraft Full Of Eels    schedule 06.10.2011
comment
Почему бы не создать JLabel внутри класса? - person Eva; 06.10.2011
comment
@eva: А, понятно - композиция против наследования... Я не знаю, в чем тут дело. Возможно, они переопределяют ключевой метод, такой как paint или paintComponent. Источник может сказать. 1+ кстати за интересный вопрос. - person Hovercraft Full Of Eels; 06.10.2011
comment
+1, за исключением того, что непрозрачность не является преимуществом. Метку необходимо сделать непрозрачной, чтобы метод setBackground() работал. - person camickr; 06.10.2011
comment
@camickr: я всегда думал, что быть непрозрачным хорошо, так как можно увидеть фон самого JList или JTable, но вы правы, когда выбраны ячейки, отображается цвет фона. - person Hovercraft Full Of Eels; 06.10.2011
comment
Расширение JLabel выгодно, потому что многие методы переопределяются, чтобы сделать отрисовку метки более эффективной. Взгляните на исходный код, если хотите увидеть все пустые методы. - person camickr; 06.10.2011
comment
@camickr: пожалуйста, измените свой комментарий выше на ответ, так как мне кажется, что это действительно самая веская причина и, следовательно, самый сильный ответ на вопрос ОП. - person Hovercraft Full Of Eels; 06.10.2011
comment
@camickr очевидно, я не согласен :-) что касается непрозрачности - DefaultTableCellRenderer использует трюк (опять же из времен паранойи производительности) - person kleopatra; 06.10.2011

Потому что каждый — даже ранняя команда Swing — имеет право время от времени делать что-то не так :-)

И неправильно расширять компонент вместо того, чтобы реализовать интерфейс рендерера и позволить этой реализации делегировать компоненту (который может быть специально реализованным JLabel со всеми свистками, которые они считают необходимыми, лично я я не уверен). Мы все еще страдаем от этого плохого решения по реализации — зловещая «цветовая память» DefaultTableCellRenderer является прямым следствием.

Итак: Не делайте подклассов некоторых компонентов для реализации некоторых Renderer. Тем более не для someComponent == DefaultTableCellRenderer, он сломан!

Кстати, SwingX делает это правильно :-)

person kleopatra    schedule 06.10.2011
comment
+1 согласен с Do-not-subclass, но я не согласен с performance_par.. что, на сегодняшнем ПК, - person mKorbel; 06.10.2011
comment
@mKorbel не понимает, с чем вы не согласны ... - вы говорите, что пустые переопределения методов в ядре DefaultXXCellRenderer необходимы, или вы говорите об обратном? - person kleopatra; 06.10.2011
comment
1) согласен со всем, что касается Renderer и SubClassing 2) не согласен с влиянием производительности современного ПК (видимое влияние) на ЖК-дисплей, 3) дело в том, что современные аппаратные средства минимизируют видимый вывод на экран с отличного, четкого и оптимизированный код и как из бардака :-) - person mKorbel; 06.10.2011