Градиентные текстовые поля на панели с TitledBorder — проблема с производительностью

У меня есть панель с 3 внутренними панелями, все из которых используют TitledBorder. На третьей внутренней панели есть несколько настраиваемых текстовых полей, окрашенных GradientPaint. Текстовые поля происходят из пользовательского класса, который расширяет JTextField и использует переопределенный метод paintComponent вместе с MouseListener, поэтому, когда мышь входит в область текстового поля, цвет градиента слегка изменяется (и снова меняется, когда мышь покидает текстовое поле).

Проблема в том, что изменение цвета градиента не очень хорошо работает, когда эти текстовые поля находятся внутри панели с TitledBorder (которая, кстати, является составной границей). Я имею в виду, что они недостаточно быстро реагируют, но хорошо реагируют, когда не находятся в такой панели (это я проверял).

Я думал, что проблема заключается в самой границе, поэтому я попытался переопределить метод paintBorder() TitledBorder, где я добавил оператор печати всякий раз, когда этот метод вызывается для рисования границы... и кажется, что каждый раз, когда мышь входит в область текстового поля ( и цвет градиента меняется) TitledBorder снова закрашивается. Если я быстро перемещаю указатель мыши по всем текстовым полям (их всего 4), то текстовые поля снова рисуются (что нормально), но составное TitledBorder также каждый раз рисуется, и я предполагаю, что это вызывает проблемы с производительностью.

Мой вопрос прост, есть ли способ, которым я могу сказать Java НЕ рисовать снова панель TitledBorder каждый раз, когда мышь перемещается по внутренним компонентам панели?

Я понимаю, что иногда это может вызвать проблемы, например, если у меня была небольшая панель с заголовком и полем со списком: если я нажал на это поле со списком, всплывающее меню могло скрыть часть границы панели (при условии, что поле со списком близко к нижней части границы). сторона), поэтому, когда само всплывающее меню снова скрыто, граница должна быть снова окрашена, иначе останется «пустая» область в месте, где всплывающее меню и граница перекрываются.

Но в предыдущем случае, когда на панели есть только текстовые поля и нет необходимости в том, чтобы граница снова рисовалась при перемещении мыши в область панели, допустимо ли предотвратить вызов paintComponent() и если да, то как? (или я должен попробовать что-то совершенно другое, о чем я не подумал - извините, я не очень опытен).

Я могу предоставить код метода градиентных текстовых полей paintComponent() и изменения, происходящего в mouseEntered(), но я думал, что причина проблемы ясна, и мое предположение о том, почему это происходит, верно (поправьте меня, если я ошибаюсь)...

РЕДАКТИРОВАТЬ:

Хорошо, просматривая свои пользовательские классы, пытаясь сделать sscce, я обнаружил свою очень глупую ошибку. Вместо стандартного TitledBorder я использовал класс CustomTitledBorder, который:

1) устранены 2 дополнительных пикселя, добавленных с правой стороны границы заголовка 2) использована составная граница и другой шрифт (полужирный палатино).

Проблема заключалась в том, что шрифт палатино не хранился в памяти, а считывался с диска каждый раз при вызове конструктора моего пользовательского класса. Таким образом, он также вызывался каждый раз, когда вызывался метод paintBorder(). И так он вызывался каждый раз, когда мышь перемещалась по текстовому полю в панели с верхней границей. Это было очень глупо, я сожалею об этом (и я пытался выяснить проблему с производительностью в течение дня и больше).

Это не отвечает на мой вопрос о том, как избежать выполнения paintBorder каждый раз, когда мышь находится над текстовым полем, но это больше не нужно (и я не совсем уверен, приемлемо ли это в любом случае).


person Rempelos    schedule 25.08.2012    source источник
comment
Публикация sscce, скорее всего, ускорит анализ вашей проблемы и поиск решений. Нам пришлось бы создать его, если бы вы этого не сделали, и ваши усилия будут высоко оценены.   -  person Hovercraft Full Of Eels    schedule 25.08.2012
comment
@HovercraftFullOfEels: спасибо за комментарий, пытаясь сделать sscce, я наконец-то понял.   -  person Rempelos    schedule 26.08.2012


Ответы (1)


Кэшируйте градиент в BufferedImage, как показано здесь и здесь. Также рассмотрите TexturePaint, проиллюстрированный здесь.

person trashgod    schedule 25.08.2012
comment
Проблема решена, но мне нравятся ваши советы по дополнительным настройкам, и я определенно собираюсь их попробовать, поэтому я принимаю этот ответ... - person Rempelos; 26.08.2012
comment
Я удивлен Font, но похоже, что вы решили проблему правильно. Вы также можете просмотреть темы по рисованию, < i>непрозрачность и оптимизированный рисунок. - person trashgod; 26.08.2012