2011-11-09 160 views
2

我有一個JScrollPane內的JPanel的東西。我在JPanel中繪製事物,並且在某些時候我可能會繪製超過JScrollPane的寬度。在這種情況下,我希望水平滾動條出現,我希望能夠滾動查看JPanel的不同部分。但是,我最終清除了JScrollPane。調整大小一個JScrollPane裏面一個JPanel,清除我畫上的JPanel

frame = new JFrame(); 
frame.setBounds(100, 100, 1000, 800); 
localScrollPane = new JScrollPane(); 
localScrollPane.setBounds(768, 6, 226, 350); 
frame.getContentPane().add(localScrollPane);   
localView = new JPanel(); 
localScrollPane.setViewportView(localView); 

drawSomeThings(localView.getGraphics()); 
// wait for user input 
int newWidth = drawThingsPastTheWidth(localView.getGraphics()); 

// these next two lines clear it 
localView.setPreferredSize(new Dimension(newWidth, localView.getHeight())); 
localView.revalidate(); 

我在做什麼錯?謝謝!

+0

不使用的getGraphics - 據我所知,這將只是生產出最有可能將超過塗(與補償的背景)下一次的paintComponent在內部調用快照。相反,請保留產生繪圖的狀態並在paintComponent中從該狀態重繪。如果速度太慢,請勾選bufferedImage並繪製圖像(如果沒有其他變化) – kleopatra

回答

4
drawSomeThings(localView.getGraphics()); 

不要使用的getGraphics()方法來作畫。下一次Swing確定組件需要重新繪製時,繪畫將會丟失。

相反的風俗畫是通過覆蓋你的組件的paintComponent()方法來完成。

+0

+1:可能是這個問題。我只專注於尺寸問題... – Heisenbug

+0

啊,所以我應該擴展JPanel(或JComponent)而不是直接繪製到JPanel? – Vinay

+0

是的。 [自定義繪畫](http://download.oracle.com/javase/tutorial/uiswing/painting/step2.html)教程將指導您完成整個過程。 – camickr

0

這樣看來,重繪被稱爲在某些時候,我沒有用擺了一段時間,所以我不能完全確定是什麼問題,但嘗試調試,並通過代碼一步一步運行看到重繪被稱爲是一個很好的起點。

+0

您的意思是重繪或重繪?我認爲它調用repaint()作爲重新驗證的一部分(需要檢查以確保)或者當我滾動條。但即使知道它調用repaint(),解決方案是什麼?我是否需要將所有東西都繪製回localView的圖形對象,還是有更好的方法?例如,如果用戶使用箭頭鍵滾動,每次用戶滾動時手動重新繪製所做的所有操作都效率低下且速度非常慢。 – Vinay

+0

就像我說過的,自從我使用swing之後已經有一段時間了,所以對於可能存在的問題我非常生疏,但可能repaint()是被調用的方法。我不確定什麼是最好的方法,顯然重新繪製屏幕效率不高,但至少它會起作用,我只是認爲指引你朝着正確的方向可能會幫助你,對不起。 – mmoon

+0

我當然感謝你的幫助。謝謝:-) – Vinay

2
  1. 請不要使用setPreferredSize方法,這裏是related thread
  2. 請勿用setBounds明確指定JScrollPane的大小。讓父母的LayoutManager處理這個問題。
  3. JScrollPane中應使用默認ScrollPaneConstants.HORIZONTAL_SCROLLBAR_​​AS_NEEDED一個 。所以 當子組件的首選大小 高於顯示區域時,滾動條應自動出現。嘗試到 重新驗證JScrollPane而不是JPanel。
+0

我明白,通常你應該使用LayoutManager;但我看不出在這種情況下會有什麼幫助。我正在繪製localview,這是一個需要可生長的表面;它基本上只是一個畫布,我不知道一個佈局管理器會檢測我是否超過了面板圖形對象的邊界。 – Vinay

+0

看看@ camickr的回答。我認爲這可能是你的問題。順便說一句,你應該總是使用適當的佈局管理器,並且不要使用應用程序代碼中的setXXXMethods。如果你依靠這些方法建立你的gui,你會很快就會遇到很多麻煩。 – Heisenbug

0

你當然應該使用重畫,而不是重新驗證。重新驗證僅將頂層的所有容器標記爲無效。

+0

調用repaint()而不是rev​​alidate()只是讓它清除我已經立即繪製到曲面上的任何東西。 – Vinay

+0

@Vinay - 這清楚地表明你正在做錯事:-) – kleopatra