动画很多图像时Java运行缓慢

时间:2016-09-05 07:56:48

标签: java animation timer jpanel

我想用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);
}  

}

1 个答案:

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