2011-11-17 61 views
4

基本上我画了很多透明的JPanel;分析显示大部分时间都用在Component.paint()中。有可能从根本上对此进行优化,因为在大多数情况下,每个JPanel的实际不透明区域非常小,例如在边缘附近。有没有办法只将特定的JPanel区域标记为不透明?

目前的情况是,重新绘制()组件将触发所有其父母重绘,因为的RepaintManager不知道脏父区域实际上是不透明的,就上去了组件层次。我在考虑在面板失效时使用markCompletelyClean()对所有父母进行调用,并使用addDirtyRegion()自己管理脏区域。

但是,是否有一种更简洁的方法来标记JPanel的特定矩形为不透明(或透明,无所谓)?

回答

2

即使你对markCompletelyClean()和addDirtyRegion()做了一些幻想,我怀疑你会获得很大的性能优势。当摆动进行重绘时,它会将所有脏区域进行整理,然后用所有脏区域的最小边界框开始重绘。因此,如果将JPanel的边界标记为脏,则JPanel的边界框与整个JPanel相同,这意味着您将以任何方式重新绘制整个事物。

+0

但是,至少它不会重新绘制一个组件的所有父母,如果我标记它们是干净的,对吧?例如,因为我有一个非常大的root不透明的JPanel,每次改变它时都会重新绘制它(以及所有导致它的所有内容),这必然会导致性能下降。 –

+0

@PhilipK他,这是一个有趣的问题,我想你的问题的核心。 Java使用画家算法,意思是从后面到前面(从父母到孩子)绘画,所以我真的没有看到任何方式让孩子在没有绘制父母的情况下绘制。但我并不是非常了解Java的绘画算法,说这是不可能的。我们不得不去看代码。你确定addDirtyRegion()不会将父母标记为脏吗? – heneryville

+0

从我收集到的情况来看,如果儿童占用的矩形发生变化,则会向家长添加脏区域,例如,由于位置或大小的变化。我想,当你有一个层次结构,比如说5个透明面板,最底层的孩子被取消时,会发生什么,因为他们都会重绘,因为每个孩子像素在理论上都会受到每个父母的影响,因为它们都是非透明的。但如果我知道肮脏的地区实际上是不透明的,我会停止在直接父母的传播链。希望有道理:) –

2

考虑使用JLabel(默认非不透明),而不是JPanel,那么你可以(在JLabel),您可以添加任何JComponent相同的JPanel,但你必须设置LayoutManager,然后你忘了关心Opacity/Transparency和细节区(S)

+1

我不太明白。与具有setOpaque(false)的JPanel相比,JLabel在性能方面的优势究竟是什么? –

1

为什么你就不能定义自己的方法myRepaint()调用多个

public void repaint(long tm, int x, int y, int width, int height) 

所有的边界?

也尝试玩clipBounds你的图形重绘只有真正必要的部分。您可以将任何自定义形状设置为剪辑。

+0

+1我的问题是没有更好的谈论EDT和paintImmediately,因为'我画了很多透明JPanels' – mKorbel

相关问题