У меня проблема с Swing, но я просто не могу найти причину.У меня есть JTextPane, который был расширен, чтобы показать фоновое изображение.Это может быть либо растровое изображение (показывается с помощью стандартных API Java), либо векторное изображение SVG (показывается с помощью SVG Salamander).
Поскольку я хочу, чтобы на текстовой панели была область вверху, используемая в качестве полякоторый не отображает текст, я делаю следующее: я перезаписываю paintComponent (), рисую фоновое изображение, затем вызываю super.paintComponent (), чтобы текст и так далее отображался, и, наконец, я рисую частьСнова фоновое изображение, но с обтравочным прямоугольником, чтобы покрыть только текст, который находится в верхней области поля.
Это прекрасно работает, за исключением небольшого сбоя, с которым я боролся в течение нескольких дней: с растровым изображением,если я выделю текст в текстовой панели, текст будет удален, а не выделен.То есть, когда я выбираю текст, фоновое изображение отображается поверх выбранных частей.Я не понимаю, почему это может быть, так как первый вызов, который рисует изображение, вызывается перед super.paintComponent (), второй вызов имеет прямоугольник отсечения, поэтому он только закрашивает поле, и все работает нормально, если я несделать выбор.Некоторые дополнительные подсказки:
- Я действительно знаю, что это что-то связанное со вторым вызовом, так как, если я прокомментирую это, у меня не возникнет этой проблемы (хотя у меня нет поля).
- Любопытно, что это не происходит, когда фон является векторным изображением, только с растровым изображением.
Вот код для моего метода paintComponent ():
public void paintComponent(Graphics g)
{
Rectangle rect = null;
if ( rasterBackgroundImage != null )
{
rect = getVisibleRect();
g.drawImage(rasterBackgroundImage.getImage(),rect.x,rect.y,rect.width,rect.height,this);
}
if ( vectorBackgroundImage != null )
{
rect = getVisibleRect();
vectorBackgroundImage.setPreferredSize(new Dimension(rect.width,rect.height));
vectorBackgroundImage.setScaleToFit(true);
vectorBackgroundImage.paintIcon(this, g, rect.x, rect.y);
}
super.paintComponent(g);
//if we want a non-scrolling top margin
if ( rasterBackgroundImage != null )
{
g.setClip(rect.x,rect.y,rect.width,getMargin().top);
g.drawImage(rasterBackgroundImage.getImage(),rect.x,rect.y,rect.width,rect.height,this);
}
if ( vectorBackgroundImage != null )
{
g.setClip(rect.x,rect.y,rect.width,getMargin().top);
vectorBackgroundImage.setPreferredSize(new Dimension(rect.width,rect.height));
vectorBackgroundImage.paintIcon(this, g, rect.x, rect.y);
}
}
Если кто-то хотел бы взглянуть на весь класс, он здесь: http://code.google.com/p/aetheria/source/browse/trunk/age/src/eu/irreality/age/swing/FancyJTextPane.java?r=301
Обратите внимание, что я не прошу исправления, так как кажется, что проблема связана с другимиклассы.Вот почему я не предоставил SSCCE: я пытался создать его, но если я использую этот класс изолированно ... он на самом деле работает.Я не смог воспроизвести проблему за пределами всей системы, и я понятия не имею, какое взаимодействие вызывает ее.Но я был бы очень признателен всем, кто давал подсказки, указывающие мне правильное направление - возможно, кто-то уже видел подобные вещи раньше и мог бы понять, что может быть причиной ...
Обновление: Мне удалось обойти проблему, прекратив использовать setClip ().Я нашел этот ответ, рекомендующий не использовать setClip () в paintComponent (): проблема отсечения качания Java
Вместо использования прямоугольника отсечения, я теперь создаю подизображение, содержащее верхнюю частьизображение, которое я хочу нарисовать на полях, и нарисовать это напрямую, не вызывая setClip ().Это, вероятно, совершенно неэффективно, так как я храню два изображения в памяти, когда одного должно быть достаточно, но по крайней мере это работает (тм).Если кому-то любопытно увидеть этот хак, он здесь (код немного грязный на данный момент): http://code.google.com/p/aetheria/source/browse/trunk/age/src/eu/irreality/age/swing/FancyJTextPane.java?r=305
Тем не менее, если кто-то сможет выяснить точную причину, почему с помощью setClip () в этомКстати, вызывает эти проблемы или знает эффективный способ решения этой проблемы, было бы интересно.Спасибо за ответы на все вопросы!:)