2013-06-26 73 views
1

我有一個圖像將在JFrame上繪製。圖像的尺寸取決於JFrame的尺寸。Swing,調整大小然後繪製

JFrame被繪製的次數明顯多於JFrame的實際大小。因此,我將圖像重新調整大小,然後將其存儲在組件重新大小事件中,並僅在繪製方法中繪製重新調整大小的圖像。

//called on componentResized 
private void scaleImage(){ 
    if((this.getHeight() * this.getWidth()) != 0) 
     scalledBackGroundImage = backGroundImage.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_FAST); 
    else 
    scalledBackGroundImage = null; 
} 

@Override 
public void paint(Graphics g){ 
    if(scalledBackGroundImage != null) 
     g.drawImage(scalledBackGroundImage, 0, 0, this); 

    super.paint(g); 
} 

但是,我似乎認爲重繪大小事件後繪畫組件被重繪時調用。因此顯示的圖像是前一幀大小的圖像。這對於最大化或最小化等操作而言確實成爲問題。

我正在尋找一種在調用paint之前檢測JFrame重新大小的方法。 (我知道我可以調用repaint()重新調整大小,但在重新調整大小時要求組件繪製兩次似乎有點粗魯)

感謝您的任何幫助。

+0

爲了更快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –

+1

在這種情況下,我會避免在每次調整組件大小時嘗試調整圖像大小,因爲可以想象,在實現組件實際大小之前,可能會調用componentResized。代替。我添加了一個'javax.swing.Timer',它有一個很短的延遲(可能是125毫秒),每次調用這個方法時'重啓'它。當定時器被觸發時,我實際上調整了圖像的大小。這減少了我可能需要將圖像調整到更合理的數量的次數,從而節省了時間和內存。 – MadProgrammer

回答

3

The Perils of Image.getScaledInstance()。這真的不是一個很好的選擇。

不僅你有上述的問題,但我得到了很多閃爍的:

import java.awt.*; 
import java.awt.event.*; 
import java.beans.*; 
import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.plaf.*; 
import javax.swing.text.*; 
import java.io.*; 

public class ResizeSSCCE extends JPanel 
{ 
    Image original; 
    Image scaled; 

    public ResizeSSCCE() 
    { 
     original = new ImageIcon("mong.jpg").getImage(); 
     scaled = original; 
     scaleImage(); 

     ComponentListener cl = new ComponentAdapter() 
     { 
      @Override 
      public void componentResized(ComponentEvent e) 
      { 
       scaleImage(); 
      } 
     }; 

     addComponentListener(cl); 
    } 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     if (scaled != null) 
      g.drawImage(scaled, 0, 0, this); 
//   g.drawImage(original, 0, 0, getWidth(), getHeight(), this); 
    } 

    private void scaleImage() 
    { 
     if (getHeight() * getWidth() != 0) 
      scaled = original.getScaledInstance(getWidth(), getHeight(), Image.SCALE_FAST); 
    } 

    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("ResizeSSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new ResizeSSCCE()); 
     frame.setSize(200, 200); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

更改使用您的圖像,然後使用縮放版本看到閃爍的運行代碼。然後更改代碼以使用飛行比例的原始圖像來查看差異。正如文章中所建議的那樣,縮放是更好的方法。

+0

同意。不要擔心,並學會愛(信任)Swing組件的雙重緩衝。 :-)專業提示:確保您使用兼容圖像,否則無論您如何進行縮放,縮放比例都會變慢。 – haraldK

1

到JFrame中添加組件監聽器

jFrame.addComponentListener(new ComponentAdapter() { 

      public void componentResized(ComponentEvent e) { 
       //Your resize method here 
      } 
     }); 
+0

我可能是錯的(這個問題有點不清楚),但我雖然這就是OP正在做的事情...... – MadProgrammer

相關問題