简体   繁体   English

图片不会在Java中绘制

[英]Image wont draw in Java

So I'm trying to draw an image onto a JFrame and I'm using the defualt toolkit as an image observer but every time I run the project it doesn't draw the image, however it will draw and move (succesfully) other shapes that I test. 因此,我尝试将图像绘制到JFrame上,并使用defualt工具包作为图像观察器,但是每次运行项目时,它都不会绘制图像,但是它将绘制并成功移动(成功)其他形状我测试。

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();            
    }
}

Your paintComponent method should do nothing bur paint. 您的paintComponent方法应该什么也不做。

    @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);
    }

The toolkit and image lines need to be in the Painter constructor. 工具箱和图像行需要位于Painter构造函数中。 Class names should start with a capital letter. 类名应以大写字母开头。

Edit based on the comment: 根据评论进行编辑:

You write code that looks like this: 您编写的代码如下所示:

private Image player;

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

The player.jpg needs to be in the same directory as the source code. player.jpg必须与源代码位于同一目录中。 Otherwise, your image directory needs to be in the classpath of your Java application. 否则,您的图像目录必须位于Java应用程序的类路径中。

Here's a complete, simple Swing application to draw an image on a JPanel. 这是一个完整,简单的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;
    }
}

Change maze.jpg to your image, and put the image in the same directory as this example code. 将maze.jpg更改为您的图像,然后将该图像放置在与此示例代码相同的目录中。

  1. Don't do I/O in a painting method. 不要使用绘画方法进行I / O。 Painting methods are for painting only. 绘画方法仅用于绘画。
  2. Don't invoke repaint() in a painting method. 不要在绘画方法中调用repaint()。 This will cause an infinite loop. 这将导致无限循环。

Read the image into a variable of your class in the constructor of your class using ImageIO so the image is available when it is time to paint the image. 使用ImageIO将图像读取到类的构造函数中的类的变量中,以便在需要绘制图像时可以使用该图像。 ImageIO will generate a message if the image is not found. 如果找不到图像,ImageIO将生成一条消息。

The final code looks like this for anyone who's interested. 对于任何感兴趣的人,最终的代码都是这样的。 The action listener wasn't included, earlier, because it was mostly irrelevant to the question. 之前未包含动作侦听器,因为它与问题几乎无关。 The reason the last snippet was included, the public painting, was because the action listener couldn't be called from inside the static main method. 之所以包含最后一个摘要(公共绘画),是因为无法从静态main方法内部调用动作侦听器。 This subclass was originally what contained all the window.* lines but was causing an infinite # of created windows so while that was moved to the main the new painting call had to be encased in a controlled loop and external from the main method. 该子类最初包含所有window。*行,但会导致无限数量的已创建窗口,因此在将其移到主窗口时,新的绘画调用必须封装在一个受控循环中,并且位于main方法的外部。 Speical Thanks to all those who helped me with this, especially Gilbert Le Blanc 特别感谢所有为我提供帮助的人,尤其是吉尔伯特·勒布朗

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);
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM