我对 Swing 有一个问题,我只是找不到原因。我有一个已扩展为显示背景图像的 JTextPane。这可以是光栅图像(通过标准 Java API 显示)或 SVG 矢量图像(通过 SVG Salamander 显示)。
由于我希望文本窗格在顶部有一个区域用作不显示任何文本的边距,因此我执行以下操作:我覆盖 paintComponent(),绘制背景图像,然后调用 super.paintComponent() 以便将显示文本等,最后我再次绘制了一块背景图像,但使用剪切矩形仅覆盖顶部边缘区域中的文本。
这工作得非常好,除了我几天来一直在努力的一个小故障:使用光栅图像,如果我在文本窗格中选择文本,文本将被删除而不是突出显示。也就是说,当我选择文本时,背景图像会显示在我选择的部分上。我不明白为什么会这样,因为绘制图像的第一个调用是在 super.paintComponent() 之前调用的,第二个调用有一个剪切矩形,所以它只在边距上绘制,如果我不这样做,一切正常t 做出选择。一些额外的线索:
- 我确实知道这与第二次通话有关,因为如果我评论它,我就没有这个问题(但我没有余量)。
- 奇怪的是,当背景是矢量图像时,它不会发生,只有光栅图像才会发生。
这是我的 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(),我设法解决了这个问题。我发现这个答案建议不要在paintComponent()中使用setClip():java swing clipping problem
我现在不使用剪切矩形,而是创建一个子图像,其中包含我想在边缘绘制的图像的顶部,并直接绘制它而不调用 setClip()。这可能效率很低,因为我在内存中存储了两个图像,而一个应该足够了,但至少它可以工作(tm)。如果有人对看到这个黑客感到好奇,它就在这里(代码现在有点脏):http ://code.google.com/p/aetheria/source/browse/trunk/age/src/eu/irreality /age/swing/FancyJTextPane.java?r=305
尽管如此,如果有人能够找出以这种方式使用 setClip() 会导致这些问题的确切原因,或者知道解决此问题的有效方法,那将会很有趣。感谢所有的答案!:)