2011-11-17 101 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

相關問題