我想用java创建一个动画游戏。但是在JPanel中拥有图像时运行缓慢而不是没有。
public class Multi_Paint extends JFrame实现了ActionListener {
JPanel pn1 = new JPanel();
JPanel pn2 = new JPanel();
static int x=100,y=100;
Timer timer;
Multi_Paint(){
setLayout(new BorderLayout());
pn1.setBackground(Color.GREEN);
pn2.setBackground(Color.red);
pn2.setPreferredSize(new Dimension(300, 300));
add(pn1,BorderLayout.CENTER);
add(pn2,BorderLayout.WEST);
setSize(1000, 1000);
setVisible(true);
pn1.add(new DrawPanel());
pn2.add(new DrawPanel());
timer = new Timer(1, this);
timer.start();
}
public void actionPerformed(ActionEvent e) {
moveBall();
repaint();
}
void moveBall(){
x=x+10;
y=y+10;
}
public static void main(String[] args) {
new Multi_Paint();
}
}
类DrawPanel扩展了JPanel {
DrawPanel(){
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize() {
return new Dimension(500,500);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x= Multi_Paint.x;
int y= Multi_Paint.y;
//If we decline this "try" Java will run faster.
try {
BufferedImage img = ImageIO.read(new File("D:\\pict1.jpg"));
double scale = 0.5 ;
double w = scale * img.getWidth(this);
double h = scale * img.getHeight(this);
g.drawImage(img, x, y, (int) w, (int) h, this);
} catch (IOException e) {
e.printStackTrace();
}
g.fillOval(x, y, 30, 30);
}
}
答案 0 :(得分:0)
就像现在一样,ImageIO.read
在内部创建ImageInputStream
,将数据写入新的BufferedImage
实例并关闭流每一帧,这是昂贵的IO操作。这就是它运行缓慢的原因。
您的paintComponent
方法中不应该有任何逻辑,否则会降低进程的速度。您应该在构造函数中读取一次的图像文件,并且只能在paint方法中访问它。由于您的图像文件在程序过程中没有变化,这就足够了。
这样的事情应该有效:
class DrawPanel extends JPanel {
private final BufferedImage img;
private int w;
private int h;
DrawPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
this.img = createImage("D:\\pict1.jpg");
}
private BufferedImage createImage(String path) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(path));
double scale = 0.5;
this.w = (int) (scale * img.getWidth(this));
this.h = (int) (scale * img.getHeight(this));
} catch (IOException e) {
System.err.println("Could not read file with path " + path);
e.printStackTrace();
}
return img;
}
public Dimension getPreferredSize() {
return new Dimension(500,500);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x= Multi_Paint.x;
int y= Multi_Paint.y;
// img could be null
if(this.img != null) {
g.drawImage(img, x, y, w, h, this);
}
g.fillOval(x, y, 30, 30);
}
}