2015-11-05 42 views
-1

所以我想繪製一個圖像到JFrame上,我使用defualt工具包作爲圖像觀察者,但每次運行項目時都不繪製圖像,但是它會繪製並移動(成功)我測試的其他形狀。圖像不會畫在Java

private class Painter extends JPanel implements ImageObserver { 

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    Toolkit tk = Toolkit.getDefaultToolkit(); 
    Image player = tk.createImage("player.jpg"); 
    tk.prepareImage(player, 50, 50, rootPane);   
    g.setColor(Color.red); 
    // g.drawRect(x, y, 50, 50); 
    g.drawImage(player, 200, 200, this); 
    window.repaint();    
    } 
} 
+0

哪裏像什麼位置? createImage將在當前工作目錄中的文件系統上尋找名爲「player.jpg」的文件 – MadProgrammer

+0

該映像位於與軟件包相同的文件夾中 – Tristan

+0

假設您的意思是該映像與類或其同一個軟件包直接在源代碼中,那麼,就是你的問題。您需要使用'Class#getResource'來獲取資源的URL,然後您可以從中加載該映像。您可以使用'ImageIO.read(getClass()。getResource(「player.jpg」))'加載圖像,但已經聲明,您不應該在paint方法 – MadProgrammer

回答

0

對於任何感興趣的人來說,最終的代碼看起來都是這樣的。之前並沒有包括行爲監聽者,因爲它與這個問題大多無關。公共繪畫中包含最後一個片段的原因是,動作偵聽器無法從靜態主要方法中調用。這個子類最初包含了所有的window. *行,但是導致創建的窗口數量無限,所以當它移動到主窗口時,新的繪畫調用必須被封裝在一個受控的循環中,並且在主方法的外部。 特殊車種零配件感謝所有那些誰與這幫助我,特別是吉爾伯特勒布朗

package painting; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.*; 
import java.io.*; 
import javax.imageio.ImageIO; 


/** 
* 
* @author tt700 
*/ 
public class Painting extends JPanel { 
    // declaring variables that control movement, show the frame, and make the picture 
    int x =50, y =50, counter = 0; 
    private static JFrame window = new JFrame("Paint a Picture"); 
    private static Painting canvas; 
    private static Image player; 


// main method 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable(){ 
    @Override 
    public void run(){  
    JLabel title = new JLabel("Making a picture frame"); 
    window.add(title, BorderLayout.NORTH); 
    canvas = new Painting(); 
    window.add(canvas); 
    player = getImage("player.jpg"); 
    window.setVisible(true); 
    window.setSize(300,300); 
    window.setForeground(Color.red); 

    } 
    }); 
} 

@Override 
// the method that does all the painting 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.drawImage(player, x, y, Painting.this); 
} 

// the method that gets a desired image and makes it displayable, with arguments it can be used to swap pictures easily 
private static Image getImage(String imagePath){ 
    Image player = null; 
try{ 
    player = ImageIO.read(Painting.class.getResource(imagePath)); 
     }catch(IOException e){ 
      e.printStackTrace(); 
     } 
     return player; 
} 
// the class that controls movement of the picture 
public class movement implements KeyListener{ 

    @Override 
    public void keyTyped(KeyEvent e) { 
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 
    } 

    @Override 
    // the method that listens to which keys are pressed and acts accordingly 
    public void keyPressed(KeyEvent e) { 
     if(e.getKeyCode() == KeyEvent.VK_RIGHT){     
     x += 5;     
     window.repaint(); 
    } 
    else if(e.getKeyCode() == KeyEvent.VK_LEFT){ 
     x -= 5; 
     window.repaint(); 
    } 
    else if(e.getKeyCode() == KeyEvent.VK_UP){ 
     y -= 5; 
     window.repaint(); 
    } 
    else if(e.getKeyCode() == KeyEvent.VK_DOWN){ 
     y += 5; 
     window.repaint(); 
    } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 
    }  
} 

// the subclass that adds a key listener to the proper component, created since action listeners can't be called in static methods (main) 
public Painting(){ 
    do{ 
    counter = 1; 
    window.addKeyListener(new movement()); 
    }while(counter < 1); 
} 

}

2
  1. 不要做I/O的繪畫方法。繪畫方法僅適用於繪畫。
  2. 不要在繪畫方法中調用repaint()。這將導致無限循環。

使用ImageIO在類的構造函數中將圖像讀入類的變量,以便在繪製圖像時可以使用該圖像。如果找不到圖像,ImageIO將生成一條消息。

3

你的paintComponent方法不應該做任何bur paint。

@Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     g.setColor(Color.red); 
     // g.drawRect(x, y, 50, 50); 
     g.drawImage(player, 200, 200, this); 
    } 

工具包和圖像行需要在Painter構造函數中。類名應以大寫字母開頭。

編輯基於註釋:

你寫的代碼看起來像這樣:

private Image player; 

public Painter() throws Exception { 
    player = ImageIO.read(getClass().getResource("player.jpg")); 
} 

的player.jpg需要在同一目錄中的源代碼。否則,您的映像目錄需要位於Java應用程序的類路徑中。

這是一個完整的,簡單的Swing應用程序,用於在JPanel上繪製圖像。

package com.ggl.testing; 

import java.awt.Graphics; 
import java.awt.Image; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class MyPanel extends JPanel { 

    private static final long serialVersionUID = -9008812738915944216L; 

    private static JFrame frame; 
    private static MyPanel panel; 
    private static Image image; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       image = getImage(); 
       frame = new JFrame(); 
       panel = new MyPanel(); 
       frame.setSize(500, 500); 
       frame.add(panel); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(image, 100, 100, MyPanel.this); 
    } 

    private static Image getImage() { 
     Image image = null; 
     try { 
      image = ImageIO.read(MyPanel.class.getResource("maze.jpg")); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return image; 
    } 
} 

將maze.jpg更改爲您的圖像,並將圖像放在與此示例代碼相同的目錄中。

+0

您能詳細說明將工具包和圖像行放入構造函數嗎? – Tristan

+0

@Tristan:我修改了我的答案。 –