В общем, сама статья выложена: http://www.skipy.ru/technics/gui_int.html. Здесь будем ее обсуждать.
Обсуждение статьи «Внутреннее устройство GUI»
В общем, сама статья выложена: http://www.skipy.ru/technics/gui_int.html. Здесь будем ее обсуждать.
-
Использование Apache Maven – обратная сторона медали
Я решил один раз высказать всё, что я думаю по поводу использования Apache Maven, ибо устал повторяться в регулярных обсуждениях этого вопроса. Плюсы…
-
До свиданья, CyberForum!
Внезапно. После нескольких лет моего активного участия в конференции CyberForum.ru, в части, посвященной Java, когда я каждый день совершенно…
-
О сборке мусора и нетривиальных конструкциях
Наткнулся на такой вопрос. Какая принципиальная разница между следующими фрагментами кода? MyObject o; o = new MyObject(); o = new MyObject();…
-
Использование Apache Maven – обратная сторона медали
Я решил один раз высказать всё, что я думаю по поводу использования Apache Maven, ибо устал повторяться в регулярных обсуждениях этого вопроса. Плюсы…
-
До свиданья, CyberForum!
Внезапно. После нескольких лет моего активного участия в конференции CyberForum.ru, в части, посвященной Java, когда я каждый день совершенно…
-
О сборке мусора и нетривиальных конструкциях
Наткнулся на такой вопрос. Какая принципиальная разница между следующими фрагментами кода? MyObject o; o = new MyObject(); o = new MyObject();…
расширение класса Highlighter
Anonymous
December 27 2010, 23:05:51 UTC 10 years ago
Спасибо Вам за статью. Как всегда эксклюзивно и в "мемориз" :).
Теперь вопрос: предположим я хочу "подсвечивать" при наведении мыши узлы в дереве (JTree), строки в таблице (JTable) или вообще свой выдуманный компонент. Если не ошибаюсь, то необходимые мне компоненты являются JLabel. Стоит ли изменить класс Highlighter для работы с JLabel и подключить его как к JTree и JTable? Или лучше обрабатывать подсветку компонентов отдельно?
С уважением, Павел.
P.S. С наступающим! Желаю всего наилучшего и почаще пишите свои статьи. Нам очень интересно.
Re: расширение класса Highlighter
February 14 2011, 13:34:01 UTC 9 years ago
JLabel не имеет никакого отношения к отрисовке компонентов дерева и таблицы. Он берется исключительно для удобства, т.е. умеет отрисовывать изображения. Я могу нарисовать свой компонент и точно также использовать в качестве CellRenderer-а.
UI JLabel переопределять, имхо, не стоит. Дело в том, что он будет работать исключительно при отрисовке, а отслеживать перемещения мыши не будет по любому - нет соответствующей компоненты на форме. Перемещения мыши могут отслеживать только JTable/JTree. Причем алгоритм определения элемента под мышью будет принципиально отличаться.
Навскидку я бы писал CellRenderer-ы (разные!) на основе JLabel, слушающие на таблице или дереве перемещения мыши. По движению они должны отслеживать, какой элемент под мышью, при смене вызывать перерисовку. При перерисовке сравнивать элементы с запомненным активным, если совпал (по ссылке!) - отрисовывать выделенным.
P.S. Сорри за задержку с ответом - запарка на работе.
Re: расширение класса Highlighter
August 11 2011, 12:12:52 UTC 9 years ago
Есть класс расш. DefaultTreeCellRenderer у которого есть метод getComponent, он возвращает JPanel, в котором два JLabel-а. При наведении мыши на узел дерева, надо определить, какой JLable находится под мышкой. Возможно ли такое сделать? Не получается Renderer-у слушать перемещение мыши.
Возможные уточнения/дополнения к статье
January 16 2011, 19:19:13 UTC 10 years ago
Также хотел бы отметить несколько вещей из Вашей статьи, которые можно было бы уточнить/дополнить...
1) К части про "Области отсечения"
Конечно, оптимизация перерисовки отсечением ненужных частей может являться неотъемлимой частью оптимизации отрисовки, но все же, как мне кажется, clip реже используется в этих целях при написании своих компонентов.
Даже если при отрисовке компонента будет стоять некий ограничивающий clip, все равно все вычисления и вызовы, которые нужны для отрисовки, будут выполнены внутри метода paint(), пока вы сами их не оптимизируете, например, проверками нахождения в видимой области и т.п.
А как показывает практика, чаще проблемы не в скорости отрисовки, а в скорости гор производимых вычислений.
Конечно отрисовкой тоже не стоит пренебрегать, но это немного другое...
По своему недавнему опыту могу сказать, что пара "неудачных" методов по вычислению места, где должна отрисоваться та или иная часть компонента, по времени исполнения перекрывают в сотни раз саму отрисовку.
Как мне кажется, clip чаще используется в двух следующих случаях:
- Стандартный clip, обрезающий отрисовку по краям компонента
В данном случае от разработчика ничего не требуется, кроме как передать управление super.paint() в начале отрисовки для установки оным стандартного clip'а
- Свой clip, необходимый для корректной отрисовки содержимого
Например если необходимо внутри компонента ограничивать отрисовки неких внутренних частей.
Главное при этом не забывать, что при отрисовке устанавливается всего 1 clip и можно нечаянно выйти за границы самого компонента, установив свой "внутренний" clip.
Но это, все же, сугубо мое личное мнение.
2) "DebugGraphics.BUFFERED_OPTION – создает отдельное окно и показывает в нем отрисовку, проводимую на буфере компоненты. Полезно при включенной буферизации. Если честно, мне не удалось включить этот режим."
Как-то давно тоже удивился, что данная опция вообще ничего не делает. Т.е. фактически - не работает.
Также на паре ресурсов по Java находил заметки на эту тему:
DebugGraphics.BUFFERED_OPTION: This is supposed to pop up a frame showing rendering as it occurs in the offscreen buffer if double-buffereing is enabled. As of the Java 2 FCS this option is not functional.
3) К части статьи - "Прозрачность компонент и смысл свойства opaque"
Я бы добавил, что opaque=true, конечно хорошо, но у него есть и обратная сторона медали.
Такая непрозрачность может сильно осложнить написание/отладку компонентов, которые могут динамически перерисовываться со временем, вне зависимости от действий пользователя.
Самым ярким примером (из доступных) являются 2 перекрывающие друг друга кнопки с установленным нативным Windows LnF в ОС WindowsVista/Windows7. Они имеют вредную привычку "моргать" при наличии фокуса.
Если их расположить друг поверх друга на панели (например) с null лэйаутом и сделать непрозрачными (setOpaque(true)), то после пары переключений/наведений минусы проявят себя во всей красе :)
Этот случай конечно немного наигранный, но он самый простой.
Я уже встречал и более сложные моменты, когда после нескольких часов мучений и гор "ужастного" кода все решалось простой установкой opaque в false (и далее, если надо, ручным отрисовыванием фона компонента).
P.S. Из того, что я отметил, вроде все :)
Было бы интересно интересно почитать схожие статьи непосредственно про производительность при отрисовке, а точнее, что-то вроде такого списка:
- Частые ошибки, приводящие к потере производительности при работе с Graphics/Graphics2D в Java
- Возможные пути оптимизации отрисовки
- Сравнения производительности разных методов Graphics/Graphics2D
- Производительность отрисовки Swing-компонентов
- Более подробное описание различий paint/paintAll/print/printAll
Возможно еще что-то в этом духе... Это то, что первое пришло в голову
Re: Возможные уточнения/дополнения к статье
January 17 2011, 10:08:08 UTC 10 years ago
4) "paintComponent – этот метод позволяет отрисовать саму компоненту. Т.е. делает то, что в AWT делал paint(Graphics). Именно этот метод необходимо переопределять для того, чтобы отрисовать что-то на компоненте. Можно, конечно, переопределить и paint(Graphics) – а те, кто начинал с AWT, часто этим грешат! – но тогда при использовании рамок (border) начнутся сложности."
Тут также важно понимать то, что метод paintComponent зачастую вызывается при частичных перерисовках компонента с разными указанными clip'ами. Также он может быть и вовсе не вызван, если перерисовываемая часть полностью закрыта opaque компонентами.
Метод же paint будет вызываться всегда при "возможной" необходимости перерисовки (будь то перекрытие другим компонентом, ресайз или что еще). Таким образом не всегда paintComponent лучше в использовании.
Тем более в сложном графическом компоненте использование его, а не paint может породить различные проблемы с перерисовкой частей.
Но для простых компонентов, когда нет смысла/времени заморачиваться с оптимизацией - да, paintCompomponent однозначно более удачный выбор.
5) Еще одно замечание к тому же paintComponent...
После части статьи про отрисовку и рамки создается немного двойственное ощущение, что использование метода paintComponent решает проблему с рамкой, т.е. (например) делает за вас отступы и подгоняет размеры (прямо, естественно об этом не говорится, но нет и обратного).
Даже лишний раз проверил реализацию метода paint/paintComponent, чтобы удостовериться, что я все еще в себе :)
Думаю, тут стоит еще раз напомнить, что замена paintComponent (вместо paint) решает проблему с отрисовкой бордера, а не с отступами, создаваемыми бордером.
Re: Возможные уточнения/дополнения к статье
February 14 2011, 13:40:44 UTC 9 years ago
Спасибо за комментарии, обстоятельно. В принципе, со всем согласен. Если соберусь пересматривать/дополнять, возможно, что-то добавлю в статью. А пока – Вы очень хорошо всё это изложили и без меня, а ссылка на это обсуждение в статье есть.
Касательно исследований производительности и т.п. - явно не сейчас. Мне на ответ найти времени - месяц понадобился.
Re: Возможные уточнения/дополнения к статье
February 14 2011, 14:18:57 UTC 9 years ago
Это само собой, просто тема мало где затронута (если вообще не проигнорирована) и хотелось бы побольше накопать в этом направлении.
Также, если интересно или нужно - могу позднее собрать некоторую долю материала по этой теме из того, что удалось самому найти/узнать на собственных ошибках при написании крупного приложения для прототипирования (фактически - сплошная работа с графикой).
В любом случае еще раз спасибо за содержательную статью!
Буду ждать продолжения :)
September 7 2012, 04:43:53 UTC 8 years ago
Единственное замечание от зануды. Согласно правилам русского языка компонент - мужского рода и только для математиков в отношении математических текстов разрешается использование в женском роде (я сам математик).
Еще раз спасибо за содержание.
Миркес.
Отрисовка компонентов
August 29 2017, 18:48:35 UTC 3 years ago
Re: Отрисовка компонентов
August 30 2017, 07:45:31 UTC 3 years ago
Насчет раскладки - есть вот такая статья: http://skipy.ru/technics/layouts.html. Там как раз есть пример круговой раскладки. Но в общем случае решение зависит от исходной задачи. А Вы пока сформулировали кусочек решения этой исходной задачи, в который Вы уперлись.