我打電話給一個聽衆重新打磨了一堆,但我設計我的油漆功能的方式只有一個需要重新繪製。我產生了一堆重繪,因爲它鉤到了我的鼠標移動偵聽器中。如何在Swing中結合重繪?
有沒有辦法取消某個組件的所有未決重繪?我不能開始忽略重繪,因爲有些是有效的,比如調整框架大小或從最小化中恢復框架。
爲什麼我在意?因爲我的油漆代碼非常沉重,而且我無法以非常高的FPS進行完全重新塗漆。
我打電話給一個聽衆重新打磨了一堆,但我設計我的油漆功能的方式只有一個需要重新繪製。我產生了一堆重繪,因爲它鉤到了我的鼠標移動偵聽器中。如何在Swing中結合重繪?
有沒有辦法取消某個組件的所有未決重繪?我不能開始忽略重繪,因爲有些是有效的,比如調整框架大小或從最小化中恢復框架。
爲什麼我在意?因爲我的油漆代碼非常沉重,而且我無法以非常高的FPS進行完全重新塗漆。
Swing將爲您重新組合繪圖:請參見Sun網站上的"Painting in AWT and Swing"。如果您快速連續安排大量重繪,他們將合併爲一個調用立即()。
我的理解是,repaint()
只是通過向重繪隊列中添加組件區域來安排重繪。如果組件上已經請求重新繪製,則新的重繪區域將與之前請求的區域建立聯合。在處理事件隊列中的所有其他事件之前,重新繪製並未實際執行。因此,您的額外重繪可能沒有太大區別,即您的繪畫代碼只能執行一次。請參閱JComponent.repaint和RepaintManager.addDirtyregion。
經常重新繪製的請求會自動合併爲一個。對此進行優化的最佳方式不是重新繪製整個事物,而是使用特定區域的座標調用repaint。這意味着您只重繪實際更改的區域。
我已經黑客類似的東西在一起,以改善JFreechart如何在繪製大量調用重畫的繪畫時決定繪畫。
基本上我做到以下幾點:
ScheduledExecutorService
作爲現場submit
它執行人在其上運行EDT中說50ms的找回了未來fut.isDone()
),如果是,則計劃下一次重繪;否則什麼都不做。這樣你每秒最多應該得到20次重繪請求。
我已經完成了類似的事情,即當同時發生大量更改時,將調用數量分配到fireDataTableChanged
。
我聽到你說的話。 您確實可以僅重繪一部分區域。 在Sun網站的「執行自定義繪畫示例」中,我找到了一個有用的示例,顯示如何繪製拖動的矩形,然後在鼠標移動或釋放時僅重新繪製該區域。
這裏是代碼的相關部分...
public void mouseDragged(MouseEvent e) {
updateSize(e);
}
public void mouseReleased(MouseEvent e) {
updateSize(e);
}
/*
* Update the size of the current rectangle
* and call repaint. Because currentRect
* always has the same origin, translate it
* if the width or height is negative.
*
* For efficiency (though
* that isn't an issue for this program),
* specify the painting region using arguments
* to the repaint() call.
*
*/
void updateSize(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect.setSize(x - currentRect.x,
y - currentRect.y);
updateDrawableRect(getWidth(), getHeight());
Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);
repaint(totalRepaint.x, totalRepaint.y,
totalRepaint.width, totalRepaint.height);
}
此代碼是受版權保護(見here for full code and copyright notice)
見here for further example listings
說實話,我在FPS上一個類似的問題,但可能是由於我目前可憐的碼!在過去的幾個月中我學到了很多東西,現在我可以讓我的代碼更加高效。希望當超過2個「人」放慢我的圖形速度時,我可以克服FPS問題! Hummmm ... 我只對我的代碼中的相同部分實施了上述代碼,而不是其他人,但通過一切手段試一試!