我对Java中的音频有些新意。我想要做的是当我播放音频时,我想重新绘制我的JComponent
,但SourceDataLine
会阻止所有其他代码行,包括其他线程。
这是我的play()
方法
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();
}
}
答案 0 :(得分:1)
显然,您在the Event Dispatch Thread上呼叫play
。例如,也许您可以通过按下按钮生成的动作事件来调用它。您需要为回放循环启动一个新线程,否则在回放结束之前GUI上不会发生任何事情。
至少,像:
new Thread(new Runnable() {
@Override
public void run() {
play();
}
}).start();
但是,您应该阅读一些并发教程(如this one),因为您似乎将访问不同线程的字段(例如byte[] arr = data;
)。
您可能还希望使用与Swing集成的SwingWorker。我在网上有一个更长的代码示例,它显示了使用SwingWorker的回放循环示例:WaveformDemo。播放循环在第310行附近。