Java 尝试在JFrame上绘制精灵时出现drawImage错误

Java 尝试在JFrame上绘制精灵时出现drawImage错误,java,swing,animation,sprite,Java,Swing,Animation,Sprite,我制作了一张非常糟糕的精灵表,它基本上只是一堆圆形和椭圆形,所以我可以掌握精灵动画 import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.Timer; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException;

我制作了一张非常糟糕的精灵表,它基本上只是一堆圆形和椭圆形,所以我可以掌握精灵动画

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

public class CircleSprite extends JFrame implements ActionListener, Runnable{

BufferedImage circles;
BufferedImage[] test;
Timer timer;
int cycle = 0;
Graphics g = getGraphics();
public void asd(){
    setSize(500,500);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    try {
        circles = ImageIO.read(new File("CircleTest.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    final int width = 206;
    final int height = 206;
    final int rows=  2;
    final int columns = 3;

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    test = new BufferedImage[rows * columns];
    try{
        for(int i = 0; i < rows; i++)
            for(int j = 0;j<columns;j++)
                {
                    test[i*columns + j] = circles.getSubimage(j * width, i * height, width, height);
                }
    }catch(Exception e){
        e.printStackTrace();
    }

    timer = new Timer(500, this);

    setVisible(true);

}

public void actionPerformed(ActionEvent e){
    //0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, etc.
    repaint();

    g.drawImage(test[cycle], 25, 25, null);


    if(cycle >= 5){
        cycle--;
    }
    if(cycle <=0){
        cycle++;
    }

}

public void run(){
    asd();

    while(timer.isRunning() == false && this.isVisible() == true){
        timer.start();
        try {
            CircleSpriteRun.t1.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

}
导入javax.imageio.imageio;
导入javax.swing.*;
导入javax.swing.Timer;
导入java.awt.*;
导入java.awt.event.*;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.*;
公共类CircleSprite扩展JFrame实现ActionListener,Runnable{
缓冲图像圆;
缓冲图像[]试验;
定时器;
整数周期=0;
Graphics g=getGraphics();
公共建筑署(){
设置大小(500500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
试一试{
圆圈=ImageIO.read(新文件(“CircleTest.png”);
}捕获(IOE异常){
e、 printStackTrace();
}
最终整数宽度=206;
最终整数高度=206;
最终整数行=2;
最终整数列=3;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
测试=新的缓冲区映像[行*列];
试一试{
对于(int i=0;i由于没有提供可运行的示例,我创建了一个示例来演示如何正确编写Swing应用程序

首先,必须使用SwingUtilities.invokeLater方法启动Swing应用程序

public static void main(String[] args) {
    SwingUtilities.invokeLater(new CircleSprite());
}
其次,应该使用JPanel而不是JFrame进行绘制。这是我创建的DrawingPanel。我的CircleSprite版本每2秒在随机位置绘制一个圆

public class DrawingPanel extends JPanel {

    private static final long serialVersionUID = -4603711384104715819L;

    private int x;
    private int y;

    private BufferedImage image;

    public DrawingPanel(BufferedImage image) {
        this.image = image;
        this.x = 0;
        this.y = 0;
        setPreferredSize(new Dimension(500, 500));
    }

    public void setPoint(int x, int y) {
        this.x = x;
        this.y = y;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, x, y, null);
    }

}
第三,在使用Swing GUI之前先创建Swing GUI。下面是CircleSprite类的run方法。我创建GUI,然后启动执行随机绘图的线程

public void run() {
    circle = createCircle();

    frame = new JFrame("Circle Sprite");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    drawingPanel = new DrawingPanel(circle);
    frame.add(drawingPanel);

    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);

    new Thread(new RandomDraw(drawingPanel)).start();
}
第四,只有当您想重写一个方法时才扩展Swing组件,就像我在DraawingPanel类中所做的那样,否则就使用Swing组件

这是整个可运行的CircleSprite类。您可以将其用作未来Swing应用程序的模型

package com.ggl.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CircleSprite implements Runnable {

    private BufferedImage circle;

    private DrawingPanel drawingPanel;

    private JFrame frame;

    @Override
    public void run() {
        circle = createCircle();

        frame = new JFrame("Circle Sprite");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        drawingPanel = new DrawingPanel(circle);
        frame.add(drawingPanel);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        new Thread(new RandomDraw(drawingPanel)).start();
    }

    private BufferedImage createCircle() {
        BufferedImage image = new BufferedImage(100, 100, 
            BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();

        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 100, 100);
        g.setColor(Color.BLUE);
        g.fillOval(10, 10, 80, 80);
        g.dispose();

        return image;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CircleSprite());
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = -4603711384104715819L;

        private int x;
        private int y;

        private BufferedImage image;

        public DrawingPanel(BufferedImage image) {
            this.image = image;
            this.x = 0;
            this.y = 0;
            setPreferredSize(new Dimension(500, 500));
        }

        public void setPoint(int x, int y) {
            this.x = x;
            this.y = y;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, x, y, null);
        }

    }

    public class RandomDraw implements Runnable {

        private DrawingPanel drawingPanel;

        private Random random;

        public RandomDraw(DrawingPanel drawingPanel) {
            this.drawingPanel = drawingPanel;
            this.random = new Random();
        }

        @Override
        public void run() {
            while (true) {
                sleep();
                int x = random.nextInt(400);
                int y = random.nextInt(400);
                drawingPanel.setPoint(x, y);
            }
        }

        private void sleep() {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {

            }
        }

    }

}

作为参考,这里有一个使用
getSubimage()
的工作。第一个错误-
Graphics g=getGraphics();
1)为了更快地获得更好的帮助,发布一个(最小完整的可验证示例)或(简短、自包含、正确的示例)。2)获取示例图像的一种方法是热链接到中看到的图像。