2016-01-02 66 views
0

基本上我需要我的一塊麪板每秒至少重漆60次。但是我注意到,如果我不移動鼠標,FPS會下降到5。我編寫了程序來測試它。Java Swing忽略repaint()?

package test; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class Test extends JFrame implements ActionListener { 

    Timer t; 
    JLabel l; 
    JPanel p; 
    long lastT; 

    public static void main(String[] args){ 
     new Test(); 

    } 

    public Test(){ 
     add(p = new JPanel()); 
     p.add(l = new JLabel("0000000000000000000000000000000")); 
     pack(); 
     lastT = System.nanoTime(); 
     t = new Timer(10, this); 
     t.setRepeats(true); 
     t.start(); 
     setVisible(true); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     long time = System.nanoTime(); 
     l.setText(String.valueOf((time - lastT))); 
     repaint(); 
     lastT = time; 
    } 

} 

它顯示幀之間的間隔。如果我的鼠標在窗口內部,它的變化速度要快得多,如果它在窗口之外,它會變得非常慢,類似於我原來的問題。但事實是,無論鼠標在裏面還是外面,數字本身都沒有太大的差別,這意味着計時器以相同的間隔拍攝事件。所以這意味着重繪()被忽略?它如何被修復?

+0

它工作正常,嘗試在另一臺機器上運行它。 – 11thdimension

回答

4

請注意,重繪不能保證工作,因爲Swing重繪管理器將忽略重疊的重繪請求 - 也就是說,如果重繪請求建立並且無法及時處理,因爲代碼是從Swing事件隊列中,只有最後一個被調用。請閱讀Painting in AWT and Swing瞭解更多信息。

但是請注意,上面的代碼中不需要調用repaint(),因爲更改JLabel模型的狀態將自行觸發重新繪製,這將重新繪製標籤本身,這應該是比在整個GUI上調用repaint更有效。還要注意,10毫秒是一個非常短的時間片,在10毫秒時可能無法準確或可靠地調用擺頻計時器。

+0

那麼,我需要在我的實際應用程序中調用repaint(),其中timer還更新對象的位置,並調用這些對象的render方法。 –

+0

@CoderinoJavarino:好的,這與你發佈的情況不同。永遠不要依賴擺動計時器完全準確,並始終根據測量的時間片來確定物理量。請閱讀[在AWT和Swing中繪畫](http://www.oracle.com/technetwork/java/painting-140037.html)瞭解更多信息。 –

+0

@CoderinoJavarino:通過調用接受Rectangle參數的重繪重載,你也可能想限制重繪到所涉及的矩形或矩形。 –