因此,对于一个个人项目,我一直试图用Java创建一个程序,该程序可以使基本的动画出现在Swing应用程序上。据我所知,我已正确完成了所有事情,并且据我所知它正在运行,但是当我运行该应用程序时,它不允许我在没有任务管理器的情况下关闭该应用程序,并且当我强制退出该应用程序时,IntelliJ会告诉您我“进程以退出代码1完成”。尽管显示了诸如线条之类的常规Graphics内容,但它也没有在屏幕上显示我的动画。

这是我的JFrame代码:

package animtest;

import javax.swing.*;

public class AnimTest extends JFrame {

    public void addComponents() {
        AnimPanel panel = new AnimPanel();
        setContentPane(panel);
    }

    public AnimTest(String string) {
        super(string);
    }

    public static void main(String[] args) {
        AnimTest frame = new AnimTest("Animation Test");

        frame.addComponents();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}


这是我的JPanel代码:

package animtest;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class AnimPanel extends JPanel {

    Image[] marsExploding = new Image[3];

    public AnimPanel() {
        try {
            marsExploding[0] = ImageIO.read(new File("res/MarsExploding.png"));
            marsExploding[1] = ImageIO.read(new File("res/MarsExploding2.png"));
            marsExploding[2] = ImageIO.read(new File("res/MarsExploding3.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void paintComponent(Graphics g2) {
        Graphics2D g = (Graphics2D) g2.create();
        g.setColor(Color.white);

        for (int i = 0; i < marsExploding.length; i++) {
            g.drawImage(marsExploding[i], (getWidth() / 2) - 128, (getHeight() / 2) - 128, 256, 256, null);

            try {
                TimeUnit.SECONDS.sleep(500);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

            g.fillRect(0, 0, getWidth(), getHeight());
        }

        g.dispose();
        repaint();
    }

}


任何帮助都将不胜感激,谢谢!

编辑1

好的,这是我的新面板代码,应该遵守Swing的合同和并发性:

package animtest;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
public class AnimPanel extends JPanel {

    Image[] marsExploding = new Image[3];

    Graphics2D g;

    int currentFrame = 0;

    public AnimPanel() {
        try {
            marsExploding[0] = ImageIO.read(new File("res/MarsExploding.png"));
            marsExploding[1] = ImageIO.read(new File("res/MarsExploding2.png"));
            marsExploding[2] = ImageIO.read(new File("res/MarsExploding3.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        Timer timer = new Timer(500, null);
        timer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                displayNewFrame(currentFrame);

                if (currentFrame < 2) {
                    currentFrame++;
                } else {
                    currentFrame = 0;
                }
            }
        });
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g2) {
        super.paintComponent(g2);

        g = (Graphics2D) g2.create();
    }

    public void displayNewFrame(int frame) {
        g.fillRect(0, 0, getWidth(), getHeight());

        g.drawImage(marsExploding[frame], (getWidth() / 2) - 128, (getHeight() / 2) - 128, 256, 256, null);
    }

}


但是,这实际上并没有在屏幕上显示任何内容。

最佳答案

Swing是一个单线程框架,这意味着任何长时间运行或在事件调度线程上下文中进行的调用都将阻止UI进行更新或允许用户与其交互,从而使您的UI看起来像如果已挂起(因为它实际上已经挂了)。

有关更多详细信息,请参见Concurrency in Swing

而不是尝试在TimeUnit.SECONDS.sleep(500);方法内使用paint,您应该有一些后台线程,该线程每隔固定的时间间隔滴答并允许您相应地更新UI。问题是,Swing也不是线程安全的,这意味着您永远不要尝试从事件调度线程的上下文外部创建或更新UI。

但是,对于基本解决方案,您可以使用Swing Timer,它将在EDT上下文中定期触发ActionListener,从而可以安全地与UI一起使用。

有关更多详细信息,请参见How to use Swing Timers

Swing中的绘制是通过一系列链接方法调用执行的,自定义绘制要求您将代码插入这些链接中的一个,最优选的是paintComponent

但是,应该通过调用要覆盖的super绘画方法来履行这些链接的约定。

有关更多详细信息,请参见Painting in AWT and SwingPerforming Custom Painting

关于java - Swing 动画不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33928135/

10-12 04:05
查看更多