我想在JFrame中加载图像,使其看起来像是视频。
为此,我认为我会更快地更改图像(20张图像/秒)
但问题是当新图像加载其显示全黑窗口时。
我不知道为什么会这样。
建议我哪里出错了。
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.io.*;
import javax.imageio.ImageIO;
class VideoI extends JPanel {
private Image img;
private Graphics graphics;
ImageIcon icon;
VideoI(){
icon=new ImageIcon("D:\\Videos\\1.jpg");
add(icon);
}
public void paintComponent(Graphics g) {
graphics=g;
repeatImgs();
}
public void repeatImgs(){
for(int i=0;i<25;i++)
{ try{
img=ImageIO.read(new File("D:\\Videos\\"+i+".jpg"));
graphics.drawImage(img, 0, 0, null);
System.out.println(""+i);
Thread.sleep(1000);
}catch(Exception e){System.out.println(""+i+":"+e);}
}
}
}
public class Video extends JFrame
{
public static void main(String args[])
{
new Video().start();
}
public void start()
{
VideoI panel = new VideoI();
add(panel);
setVisible(true);
setSize(1300,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
答案 0 :(得分:1)
您正在将事件调度线程(UI更新线程)发送到睡眠状态,这就是您遇到屏幕问题的原因。
尝试在工作线程中加载和切换图像(查看SwingWorker
JavaDoc)。
答案 1 :(得分:1)
我不是Swing所期待的,但我猜这会发生,因为你用Thread.sleep
停止了Swing线程。您应该在摆动线程之外进行图像更改和计时,并使用SwingUtilities.invokeLater
绘制图像。你也需要睡50ms,而不是20fps的整秒。使用ScheduledExecutorService适合这里。
此外,当需要渲染时,您始终从光盘加载图像。这可能会变慢。最好在启动时加载所有图像,然后只需更改图像。
答案 2 :(得分:1)
您正在阻止事件派发线程。使用摆动Timer以所需频率重新绘制组件。
你永远不应该在EDT中sleep()
。你想要的基本上是
public void paintComponent(Graphics g) {
// No loops or delays, just fetch the next image, preferrably it has been
// already been loaded by another thread.
g.drawImage(getNextImage(), 0, 0, null);
}
计时器任务:
ActionListener timerTask = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
panel.repaint();
}
};
Timer timer = new Timer(50, timerTask);
如果您想要启动视频,请拨打timer.start()
。
最后,您还应该使用SwingUtilities.invokeLater()
包装创建GUI。