问题
I am somewhat new to audio in Java. What I am trying to do is as I am playing audio, I want to repaint my JComponent
, but the SourceDataLine
blocks all other lines of code including other Threads.
Here is my play()
method
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:
Evidently you're calling play
on the Event Dispatch Thread. For example, maybe you call it from an action event generated by a button press. You need to start a new thread for the playback loop, otherwise nothing can happen on the GUI until playback ends.
At the very least, something like:
new Thread(new Runnable() {
@Override
public void run() {
play();
}
}).start();
However, you should read some concurrency tutorials (like this one) as it seems you will be accessing fields across different threads (such as whatever byte[] arr = data;
is).
You may also wish to use SwingWorker which has some integration with Swing. I have a somewhat lengthier code example online that shows an example of a playback loop using SwingWorker: WaveformDemo. The playback loop is around line 310.
来源:https://stackoverflow.com/questions/21373231/cannot-do-anything-while-writing-to-a-sourcedataline