我一直试图将图片加载到这个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指令,我会在面板中看到一个圆圈。非常感谢,非常感谢。
答案 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);
}