添加计时器后,图像将不再加载

时间:2019-07-09 16:15:03

标签: java swing timer

我正在尝试创建一个Asteroids游戏,但一开始我就很努力:我想在游戏开始之前创建一个倒数计时。为此,我使用了一个计时器,该计时器在按下“启动”按钮时启动,并且(应该)每秒加载一个BufferedImage,然后将其显示在JFrame上。

在添加计时器之前,整个过程运行良好。但是,图像仍在绘制中,run()的方法TimerTask仍在使用中。但是,该图像没有出现在我的JFrame上。

public class Main implements ActionListener {

    private static File load = null;
    private static BufferedImage image = null;
    private JFrame frame;
    private JButton start;
    private JLabel game_name;
    private JLabel screen;
    private ImageIcon icon;
    private Asteroids aster = new Asteroids();
    private static Main m = new Main();

    protected static int height = 550;
    protected static int width = 800;
    protected static int cd = 0;

    /*
     * Here the JFrame frame gets created and set up, and the main method 
     * does its job. I believe only the actionPerformed method to be 
     * important, so I removed this part from the post.
     *
     */


    private void addScreen() {
        frame.add(screen);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        // Cleaning the screen
        start.setVisible(false);
        game_name.setVisible(false);

        // Creating the image
        aster.spawn(5);

        // creating the countdown timer
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {            
            public void run() {
                // creating countdown
                aster.initialScreen();

                // Reading the image
                load = new File(aster.filePath + aster.fileName + ".png");
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                try {
                image = ImageIO.read(load); 
                } catch (IOException i) {
                    System.out.println("Reading has encountered an error: \n" + i); }

                // Implementing the Image
                screen = new JLabel();
                screen.setSize(width, height);
                icon = new ImageIcon(image);
                screen.setIcon(icon);
                m.addScreen();
                System.out.println("roger");
            }

        }, 0, 1000);

    } // end actionPerfomed()

} // end class

有人可以发现错误吗?我真的不明白问题是什么,虽然我是定时器的新手,所以如果我做的真的很愚​​蠢,请告诉我。

2 个答案:

答案 0 :(得分:1)

您的问题很可能是因为您正在使用java.util.Timer,它会启动其自己的后台线程并在访问Swing组件时导致并发问题。

无论如何,我建议使用javax.swing.Timer,它将您的任务安排为要在Swing事件分配线程上执行的动作侦听器:

new javax.swing.Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            // Your code here
        }
    }).start();

答案 1 :(得分:0)

好的,所以我以某种方式解决了这个问题: 首先,我确实将util.Timer更改为swing.Timer,但这本身并没有帮助。 以前,在将每个图像绘制到桌面上之后,我要保存它们,然后将其加载到屏幕上以显示它。我花了一些时间处理代码,发现不需要保存它,但实际上可以通过将其设置为static来直接引用它。当我这样做时,问题就消失了。这是我的意思的代码示例:

之前:

// In the drawing class
save = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    ImageIO.write(image, "png", save); 
    } catch (IOException i) {
    System.out.println("Writing has encountered an error: \n" + i); }

// In the displaying class
load = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    image = ImageIO.read(load); 
    } catch (IOException i) {
    System.out.println("Reading has encountered an error: \n" + i); }
ImageIcon icon = new ImageIcon(image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

之后:

// One static declaration and initialization of an BufferedImage in the drawing class
public static BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Drawing Code

// Accessing the image
ImageIcon icon = new ImageIcon(DrawingClass.image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

从本质上讲,所有内容都是相同的,只是跳过了整个保存和读取过程,而我只使用一个BufferedImage而不是几个本地static BufferedImage

我不确定为什么会这样,但是我的猜测是,整个读取和写入过程花费的时间太长,以致于Timer每秒无法启动,而且这种新方法要快得多。我没有尝试再次使用util.Timer来完成整个操作,但是我认为swing.Timer在解决此问题方面可能有其应有的份额。