放置在循环中时,JLayer Player会覆盖SWT小部件的刷新

时间:2014-05-17 06:59:40

标签: java eclipse swt jlayer

我正在尝试创建一个应用程序,在音频完成后检索图像和.mp3文件并从一个图像转换到下一个图像。我在这些图像之间转换的基础框架有点复杂,但我已经设法在SWT中获得一个动作,成功地使我能够手动从一个转换到下一个。但是,当我试图将其自动化时,出现了一个问题;当放入循环时,我的playAudio()方法在我在displayShow()方法中进行的所有调用都已解决之前开始,这导致一个空白窗口,尽管音频仍在播放。

以下是我要开始演出的动作的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但仍然无法解决我的问题。我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

audioLatch.await()阻塞主程序线程,这是所有SWT操作都运行的线程,因此Display.asyncExec runnables只是排队,直到线程可用。

如果你真的必须在playAudio方法中等待,你可以在那里运行显示事件循环,直到后台线程结束:

while (! background thread finished)
 {
   if (!display.readAndDispatch())
     display.sleep();
 }