2011-02-05 87 views
1

嗨我一直在嘗試通過改變我提出的mandelbrot集的程序來攪亂Java GUI,但是當我在paint方法中放置if語句時,它會使圖像在屏幕,然後抹去黑屏。Java Paint方法閃爍並消失

這是我的paint方法:

public void paintComponent(Graphics g) 
{ 
    if (clicked == false && count == 0) 
    { 

     drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set 
     clicked = !clicked; 
    } 

    zoom(g); 
    repaint(); 

} 

public void zoom(Graphics g) 
{ 

    if (count > 0 && clicked == false) 
    { 
     g.setColor(Color.white); 
     g.fillRect(0,0, 400, 400); 

     clicked = !clicked; 
    } 
} 

我知道,因爲它的工作之前有提錯的drawMandelbrot()函數,並且我知道,它不應該是因爲計數變焦()函數僅在mousePressed時增加。

有什麼想法?我嘗試過評論這麼多部分,有時會留在屏幕上,但我再次運行它,但沒有。 Swing/AWT這個不可靠嗎?

UPDATE:

我想通了,這個問題曾與設置背景顏色做。我在主函數中設置了框架的背景顏色,但由於某種原因(我仍然不知道)在繪製圖像之後,它將背景顏色再次設置在其上。

public Mandelbrot (int w, int h) //constructor method that is only utilized to bring in the size of the screen 
{ 
    this.setBackground(Color.BLACK); 
    addMouseListener(this); 
    clicked = false; 
    count = 0; 
} 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    if (clicked == false && count == 0) 
    { 

     drawMandelbrot(g); //sends graphics object to the method that draws the Mandelbrot set 
     clicked = !clicked; 
    } 

    zoom(g); 

} 

public void zoom(Graphics g) 
{ 

    if (count > 0 && clicked == false) 
    { 
    } 
} 
public void mouseReleased(MouseEvent e) 
{ 
     zoomX = e.getX(); 
     count ++; 
     clicked = !clicked; 
     repaint(); 
     System.out.print(clicked); 
} 

更新2: 它仍然不能正常工作,它的工作是第一次,但我試圖再次運行它,同樣的事情發生以前一樣,它採用了黑色邊框結束。

+0

是不是paintComponent()更新`clicked`變量使得zoom()中的檢查不會觸發? – 2011-02-05 21:32:48

+0

看到paintComponent()方法中的repaint()調用會傷害我的眼睛,如果JVM不智能,會導致不停的遞歸。爲什麼試圖在那裏調用這個方法? – 2011-02-05 22:54:01

回答

1

在方法調用的頂部調用super.paintComponent()以使Swing句柄繪製組件的其餘部分。有關painting components in Swing的更多信息,請參閱此文章。但基本上,paintComponent()方法正在繪製您嘗試顯示的組件的實際工作,當您覆蓋它時,所有組件都會被禁用。通過調用super.paintComponent()你有Swing做它需要做的事情來正確繪製一切,然後它繪製你想繪製的東西。

更新 我想知道這是不是與你的邏輯有關的「點擊」。當你打電話給repaint()時,它從頭開始重新整修整個面板。這意味着如果你想要一些東西持續存在,你需要a)不要打電話重畫,也不要讓Swing調用重畫,例如調整窗口大小;或者b)確保你的重繪方法總是能繪製你想要的東西。一般來說,b)是更好的方法,因爲它更健壯。

因此,我會讓你嘗試重構你的代碼,使其在paintComponent()方法中沒有任何條件,這樣無論調用多少次,該對象仍然會被繪製。

您可能遇到的問題(大概這就是爲什麼您按照您的方式構建代碼的原因)是構建要繪製的對象所花費的時間可能太長,無法一直重繪。如果這是一個問題,則需要重新編寫程序的邏輯,以便計算想要在另一個線程中繪製的內容(請參見SwingUtilities.invokeLater()),然後在調用paintComponent()時只需繪製之前計算的值。

0

將一個System.out.println(清單中的相關變量);在每個方法的開始,所以你得到它是存在的秩序的清晰畫面。

這將是有益的知道zoom(g)會發生什麼,你沒有包括那個。

您也可以更正帖子,以便mouseReleased方法的格式正確。我第一次錯過了! :)

一些邏輯似乎有點...如果。

這兩個if語句檢查clicked==false但這隻會是每個鼠標釋放後第一個paintComponent。我不是一個Swing專家,我只能基於AWT的知識,但是不會經常調用paintComponent函數嗎?它可能畫一次,然後被召回,並再次繪畫 - 只有這一次(clicked==false)是真實的。因此,'閃光'。

我會建議將mandlebrot繪製到圖像上,然後使用getGraphics().drawImage(img, 0, 0 null);將圖像複製到組件上,然後您只需在每個油漆中將現成的圖像曝光。

以下代碼完全未經測試。我對此不承擔任何責任。 ;-)

BufferedImage mbrot = null; 
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    if (mbrot==null || mbrot.getWidth()!=getWidth() || mbrot.getHeight()!=getHeight()) 
    { 
     mbrot = new BufferedImage(getWidth(), getHeight(), null); 
    } 
    if (clicked == false) 
    { 
     Graphics mg = mbrot.getGraphics(); 
     if (count==0) 
     { 
      drawMandelbrot(mg); //sends graphics object to the method that draws the Mandelbrot set 
      clicked = !clicked; 
     } 
     else 
     { 
      zoom(mg); 
     } 
     mg.dispose(); 
    } 
    g.drawImage(mbrot, 0, 0, null); 
}