簡體   English   中英

在Java中使用super.paintComponent(g)或getGraphics()

[英]use super.paintComponent(g) or getGraphics() in java

我對幾件事有些困惑:

示例代碼,顯示了我的問題,這是無法編譯的

// image
private BufferedImage image;
private Graphics2D graphic;
private changeImage;
. . .
//thread loop
while (running) {
   . . .
    render();
    Graphics showGraphic = getGraphics();
    showGraphic.drawImage(image, 0, 0, null);
    showGraphic.dispose();
    }
 public void render(){
     if(changeImage == 1)
     graphic.drawImage(ImageLoader.TREE, 0, 0, null);
     else if(changeImage == 2){
     graphic.drawImage(ImageLoader.HOUSE, 0, 0, null);
      . . .
     graphic.fillRect(50,60,30,40);
     }
}

我創建了一個全局對象Graphic2D並在render()繪制了東西,我沒有在游戲循環內調用repaint() ,這樣做是一種好習慣嗎?

我是否應該在循環中使用repaint()paintComponent()函數?

另一件事, graphic.dispose()如何正常工作? ,因為嘗試刪除此行代碼,因此沒有任何反應。

我了解根據java docs的dispose()的工作方式但是我沒有注意到dispose()與否的任何區別。

我的程序運行得很好,但是我有這個問題。

這樣做是一種好習慣嗎

不,這實際上非常可怕且容易出錯。 假定這是Component#getGraphics方法。 問題是Swing使用被動渲染算法,也就是說,Swing決定何時以及應重新繪畫的對象,並且出於優化原因進行此操作。

這意味着更新不是定期的,這在制作動畫時確實有幫助,並且可以出於多種原因隨時發生,其中許多原因是您根本無法控制的。

由於這些原因,應該在一種繪制方法(最好是基於JComponent的類的paintComponent內完成JComponent 這樣,當Swing決定進行重新繪制時,一個您知道它並可以相應地更新輸出,第二個它不會清除您先前使用getGraphics對其繪制的內容,這可能會導致閃爍...

當線程試圖繪制到Graphics上下文時,您還遇到了潛在的線程問題,因此Event Dispatching Thread可能不會很完美地結束...所有繪制都應在EDT(用於基於組件的繪畫)

您可以嘗試使用BufferedStrategy ,它可以使您直接控制繪畫過程,但這將您限制在AWT庫中。 不知道這對您而言是好是壞。

另一件事,graphic.dispose()如何正常工作? ,因為嘗試刪除此行代碼,因此沒有任何反應。

基本上, dispose釋放Graphics上下文可能持有的所有本機資源。 一般的經驗法則,如果沒有創建,就不要丟棄它。

因此,如果使用Graphics#createBufferedImage#createGraphics獲取Graphics上下文,則在完成dispose后應調用dispose

在某些系統上,在用於執行組件繪制(例如,傳遞給paintComponent或從getGraphcis獲得的組件)的Grpahics上下文中調用dispose可以防止進一步繪制內容。

同樣,不處理已創建的Graphics上下文會導致內存泄漏,因為它們不會收集垃圾。

關於Swing中“好”或“正確”繪畫的問題很多,因此可以將此問題視為重復問題,在此我將不重復在上下文中應閱讀的內容,例如,在《 表演課》中習俗繪畫

但是,簡要扼要地總結最重要的信息:

  • 永遠不要Component上調用getGraphics 它可能返回null或以任何其他方式“無效”的Graphics對象。 遲早會以一種或另一種形式失敗
  • 您應該使用在此接收到的Graphics對象作為參數,在paintComponent方法(或從paintComponent調用的方法)中進行所有繪畫操作。
  • 是否調用Graphics#dispose方法可能不會使“立即”可見的差異。 應該調用它,你在收到的一個paintComponent 只能在從BufferedImage獲得或通過調用Graphics#create()Graphics對象上調用它。 當您不調用它時,這可能會導致內存泄漏,只有在應用程序運行了一段時間后,才會注意到該泄漏。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM