在我的应用程序中,用户可以记录2秒的帧数(30 fps)。我正在使用xbox kinect录制深度直方图。
记录的2秒结果是60个BufferedImage实例的数组。
我想要实现一个播放'选项将打开一个新的JFrame,其中60个图像将以每秒30个图像显示。
我对如何处理此功能感到有些困惑。我需要每隔33ms重新绘制一次该组件以达到30fps,但是如何在不阻塞用户界面的情况下停止重绘?这是我到目前为止所测试的:
package view;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* Created by X on 15/08/16.
*/
public class PlaybackView extends Component {
private BufferedImage[] images;
private int counter = 0;
public PlaybackView(BufferedImage[] images){
this.images = images;
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(images[counter], 0,0, this);
}
public void run(){
while (counter < 60){
repaint();
try {
Thread.sleep(33);
}catch (InterruptedException e){}
counter++;
}
}
}
在这段代码中创建了实例:
btnPlayback.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TreePath[] paths = treeRecordings.getSelectionPaths();
for (int i = 0; i < paths.length; i++){
if (mapper.get((DefaultMutableTreeNode) paths[i].getLastPathComponent()) != null){
Recording recording = mapper.get((DefaultMutableTreeNode)paths[i].getLastPathComponent());
JFrame quickframe = new JFrame("Playback " + recording.getEntry().getName() + " - " + recording.getNumber());
PlaybackView player = new PlaybackView(recording.getPlayback());
quickframe.add(player);
quickframe.setVisible(true);
player.run();
quickframe.dispose();
return;
}
}
JOptionPane.showMessageDialog(null, "No valid selection of recordings", "Error", JOptionPane.ERROR_MESSAGE);
}
});
创建的Frame以最小的大小开始(无法看到任何内容)并且无法打开(我认为因为在ui线程上调用了Thread.sleep())。什么是解决我的问题的最佳方法?
由于
答案 0 :(得分:0)
管理自己解决问题所以我会留下我的解决方案,以防它可以帮助他人。
使用每33毫秒触发一次的Timer实例(swing)。
我的班级现在看起来像这样:
package view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
/**
* Created by xyz on 15/08/16.
*/
public class PlaybackView extends Component {
private BufferedImage[] images;
private Timer timer;
private int counter = 0;
public PlaybackView(BufferedImage[] images){
this.images = images;
timer = new Timer(33, new TimerListener());
timer.start();
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(images[counter], 0,0, this);
}
private class TimerListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
repaint();
counter = (counter + 1) % 60;
}
}
}
干杯