我正在尝试制作一个应用程序,用于检索图像和.mp3文件,并在音频完成后从一个图像切换到下一个图像。我在这些图像之间转换的底层框架有点复杂,但我设法在SWT中获得了一个成功的操作,使我能够手动从一个转换到另一个。但是,当我尝试将其自动化时,出现了一个问题;当放置到一个循环中时,我的playAudio()方法在我的displayShow()方法所做的所有调用都已解决之前就开始了,这会导致一个空白窗口,尽管音频仍在播放。JLayer Player放置在循环中时覆盖SWT小部件的refesh
这里是我要开始表演动作的run方法:
Action startAction = new Action("Start") {
public void run() {
//do {
displayShow();
playAudio();
//} while(true);
}
};
这里是playAudio()。我能够播放音频平安无事:
public void playAudio() {
final String audio = "Happy_Birthday.mp3";
audioLatch = new CountDownLatch(1);
audioThread = new Thread() {
public void run() {
try {
Player player = new Player
(new BufferedInputStream
(new FileInputStream(audio)));
player.play();
audioLatch.countDown();
} catch (JavaLayerException e) {
} catch (FileNotFoundException e) {
} catch (Exception e) {
}
}
};
audioThread.start();
try {
audioLatch.await();
} catch (InterruptedException e) {
}
}
这里是displayShow():
private void displayShow() {
new Thread() {
public void run() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
Control[] children = container.getChildren();
for (int i = 0; i < children.length; i++) {
children[i].dispose();
}
show.showSlide(container);
container.layout();
}
});
}
}.start();
}
show.showSlide返回复合,其父母为容器,这是最高的直接子父母组合。在新创建的组合中,将图像添加到标签,并将标签的父级分配给组合。我意识到displayShow()是否在单独的线程中似乎不重要;这只是我尝试的最后一件事。
这不仅仅是增加了导致刷新不执行的循环。我可以通过playAudio()方法删除CountDownLatch,我可以让手动转换工作。如果我删除这个锁存器,将这两个方法封装在一个循环中的唯一方法是嵌入while循环,这似乎占用了相当数量的CPU,但仍然无法解决我的问题。我错过了什么?
这工作,非常感谢你。我在演奏音乐的过程中等待并不是必须的。你会在哪里做到这一点? –
我有一个基于JavaZoom BasicPlayer的播放器 - 它使用监听器在播放器线程完成时通知主线程。因此,您在播放开始时禁用“播放”按钮,并在侦听器被调用播放结束时再次启用。 –
按照您第一次建议的方式完成后,在每次转换后,音频结束和下一次移动之间的等待时间似乎正在增加。有没有办法强制显示屏醒来? –