2014-01-27 27 views
0

我对Java中的音频有点新鲜。我试图做的是在播放音频时,我想重新绘制JComponent,但SourceDataLine会阻止其他所有代码行,包括其他线程。 这里是我的play()方法写入SourceDataLine时无法执行任何操作

public void play() 
{ 
    final AudioFormat af =new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); 
    SourceDataLine line; 
    try { 
     line = AudioSystem.getSourceDataLine(af); 
     line.open(af, Note.SAMPLE_RATE); 
     line.start(); 
     byte[] arr=data; 
     for(int position=0;position<arr.length;position++) 
     { 
      byte[] out={arr[position]}; 
      line.write(out, 0, 1);  //Blocks all user input (Mouse and Keyboard) 
      this.repaint();    //Need to repaint JComponent here 
     } 
     line.drain(); 
     line.close(); 
    } catch (LineUnavailableException e) { 
     e.printStackTrace(); 
    } 
} 

回答

1

显然你调用the Event Dispatch Threadplay。例如,也许你从按钮按下时产生的动作事件中调用它。您需要为播放循环启动一个新线程,否则在播放结束前,GUI上不会发生任何事情。

最起码,是这样的:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     play(); 
    } 
}).start(); 

然而,你应该读一些并发的教程(如this one),因为它似乎你将访问在不同的线程领域(如任何byte[] arr = data;是)。

您也可以使用SwingWorker,它与Swing有一些整合。我有一个比较长的代码示例,它展示了一个使用SwingWorker的回放循环示例:WaveformDemo。播放循环在310行左右。

相关问题