gpt4 book ai didi

java - Swing 动画不起作用

转载 作者:行者123 更新时间:2023-12-02 04:09:31 24 4
gpt4 key购买 nike

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

这是我的 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了解更多详情。

不要尝试在 paint 方法中使用 TimeUnit.SECONDS.sleep(500); ,您应该有一些后台线程,它定期运行并允许您相应地更新 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com