2011-09-06 58 views
4

只是使用繪畫方法和我的圖像最初不會顯示。一旦我最小化Java窗口並調整它,圖像顯示出來。有沒有我錯過的代碼?好奇爲什麼我的圖像沒有出現

public class Lil extends JFrame { 

Image image = Toolkit.getDefaultToolkit().getImage("images/Untitled.png"); 

public Lil(){ 

    setTitle("flame"); 
    setBackground(Color.WHITE); 
    setSize(400, 400); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setResizable(false); 
    setVisible(true); 
} 

public void paint(Graphics g){ 

    g.clearRect(0, 0, 400, 400);   
    g.drawImage(image, 60, 25, null); 
    //repaint(); 
} 

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

回答

7

不要在一個JFrame直接繪製。而是繪製一個JPanel的paintComponent方法,然後將該JPanel添加到您的JFrame的contentPane中。更好的是,如果您不打算將圖像組件用作容器(用於容納其他組件),只需使用Image創建一個ImageIcon,通過其構造函數或setIcon方法將該圖標放入JLabel中,並簡單地顯示JLabel。沒有麻煩,沒有大驚小怪,沒有麻煩。另外,如果您調用super的paintComponent方法作爲JPanel的paintComponent重寫方法中的第一個調用,則可能不需要調用clearRect。

舉例來說,如果要直接在一個JPanel繪製的更爲複雜的路線,你會做像這樣的東西:

import java.awt.*; 
import java.awt.image.*; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

public class Lil extends JPanel { 

    private static final String URL_PATH = "http://duke.kenai.com/Oracle/" + 
     "OracleStratSmall.png"; 

    BufferedImage image = null; 

    public Lil() { 
     setBackground(Color.white); 
     try { 
     image = ImageIO.read(new URL(URL_PATH)); 
     } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (image != null) { 
     return new Dimension(image.getWidth(), image.getHeight()); 
     } 
     return super.getPreferredSize(); // default 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (image != null) { 
     g.drawImage(image, 0, 0, null); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      Lil lil = new Lil(); 

      JFrame frame = new JFrame(); 
      frame.getContentPane().add(lil); 
      frame.setTitle("flame"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setResizable(false); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     } 
     }); 

    }  
} 

同樣,只有做到這一點,如果你要上放置元件圖像如文本字段,按鈕等等。如果沒有,那麼使用更簡單的ImageIcon/JLabel的想法。

+0

嗯......當我閱讀OP的意圖是在框架上有一個背景圖像。如果是這樣,您必須將面板設置爲contentPane而不是添加它。或者我錯過了什麼? – kleopatra

+3

+1用於熱鏈接到圖像。順便說一句 - 在所有的興奮中,我想每個人都忘記回答OP的確切問題。所以對於記錄來說,之前的問題是使用非阻塞的'Toolkit'方法來加載圖像。上面貼出的代碼使用'ImageIO',它在繼續下一個代碼行之前讀取整個圖像。 –

+0

@kleopatra:我同意,如果圖像是背景,那麼顯示它的組件應該成爲contentPane。 –

0

氣墊船已經添加了一些建議,所以不重複這些。

您的代碼不起作用,因爲當您重寫paint()時,您還沒有調用超類塗裝方法。

只需在您的paint()方法的結合中添加一行。像這樣:

public void paint(Graphics g) { 
    super.paint(g); 
    g.clearRect(0, 0, 400, 400); 
    g.drawImage(image, 60, 25, null); 
    // repaint(); 
} 
+1

但是,不要重寫'paint',而是重寫'paintComponent',並且如我的答案中所述,在此方法中調用'super.paintComponent'。 –

+0

@ Hovercraft:哦,謝謝。我想在我的答案結尾處添加該部分。我只是忘了:)你提到的好。 – Mohayemin

相關問題