将图像放在java JFrame中

时间:2014-04-03 23:45:32

标签: java swing jframe jpanel draw

我一直试图将图片加载到这个JFrame中,以便显示它而没有成功。这是代码:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JOptionPane;

public class Main extends JPanel{

Bird bird = new Bird(this);

public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2D = (Graphics2D) g;
    g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    bird.paint(g2D);
}

public static void main(String[] args)throws InterruptedException{
    JFrame frame = new JFrame("Java Birds");
    Main game = new Main();
    frame.add(game);
    frame.setSize(500, 300);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    while(true){
        game.repaint();
        Thread.sleep(10);
    }
}
}

这是我的鸟类:

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;

public class Bird {
    private static final Image sprite = Toolkit.getDefaultToolkit().getImage("bird.jpeg");
    private static final int DIAMETER = 30;
    double g = 0.12, vy = 0, xo = 100, yo = 10;
    private Main game;

    public Bird(Main game){
        this.game = game;
    }

    public void paint(Graphics2D g){
        g.setColor(Color.BLACK);
        g.drawImage(sprite, 30, 30, game);
    }
}

当我运行时,屏幕上没有显示任何内容,但是如果我放置g.fillOval指令,我会在面板中看到一个圆圈。非常感谢,非常感谢。

2 个答案:

答案 0 :(得分:3)

有一系列问题,首先......

public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2D = (Graphics2D) g;
    g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    bird.paint(g2D);
}

您要覆盖paint,这是非常不推荐的,相反,建议您覆盖paintComponent

另一个问题是......

Toolkit.getDefaultToolkit().getImage("bird.jpeg");

问题是getImage(String)期望您传递的值是指文件系统上的文件。在大多数情况下,情况并非如此,图像存储为嵌入式资源,使用时需要使用更像......

Toolkit.getDefaultToolkit().getImage(Bird.class.getResource("bird.jpeg"));

Toolkit.getDefaultToolkit().getImage(Bird.class.getResource("/bird.jpeg"));

仍然无法保证图像已加载,并且这些方法实际上都没有告诉您何时失败。

更好的解决方案是使用ImageIO来阅读图片,除了支持更多格式之外,它会在失败时抛出IOException ...

public class Bird {
    private Image sprite;
    //...
    public Bird(Main game) throws IOException {
        image = ImageIO.read(getClass().getResource("/bird.jpeg"));

此...

while(true){
    game.repaint();
    Thread.sleep(10);
}

也非常危险,你已经在main方法中启动了这个,但你没有考虑调用哪个线程main。在“正常”操作中,{ {1}}由JVM从所谓的“主线程”调用,不能保证这就是你的main方法的调用方式。它可能会被另一个类从EDT的上下文调用,这会导致程序冻结。

通常,您应该使用main或单独的线程。

答案 1 :(得分:0)

要显示填满整个面板的图像,您应该具有以下内容。您可以使用ImageIO.read(File)从文件中读取图像(您可以在paintComponent方法中调整图像的位置和大小)。您可能还想看到Graphics.drawImage`

import javax.swing.*;
import java.awt.image.*;
import java.awt.*;

public class PictureFrame extends JComponent{

    private final Image img;


    public PictureFrame(final String file) throws IOException {
        this(new File(file));
    }

    public PictureFrame(final File file) throws IOException {
        this(ImageIO.read(file));
    }

    public PictureFrame(BufferedImage img){
        this.img = img;
        this.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
    }

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

        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
    }
}

测试人员主要:

public static final String TEST_FILE = "file path here";

public static void main(String... args) throws IOException {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
    }

    final JFrame frame = new JFrame();
    final JComponent picture = new PictureFrame(TEST_FILE);
    frame.setContentPane(picture);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500, 300);
    frame.setVisible(true);
}