在线查看之后,我发现了一个类的简单示例,它显示了三个左右的线程同时工作。但我似乎无法将其纳入我的计划。我正在制作一个声音板,利用数字键盘上的1-9键,按下时应该播放声音位,但仍然允许其他键发出按下的声音或识别它已被释放并停止播放。但即使(我认为)我有一个多线程系统设置,一个线程完全控制程序,播放一个音频文件完成。
这是程序的主要内容:一个实现Runnable的简单框架,在Launcher类中创建并启动。它有“圆”对象,在帧上数字键盘的位置显示红色圆圈,如果按下相应的数字,则变为蓝色。它还包含一个实现Runnable的SoundButton ArrayList。
框:
public class Frame extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;
private Pane pane;
private ArrayList<Circle> c;
private ArrayList<SoundButton> SB;
private KeyManager keyManager;
public Frame(ArrayList<SoundButton> soundButton){
keyManager = new KeyManager();
this.addKeyListener(keyManager);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setPreferredSize(new Dimension(400, 400));
this.pack();
this.setLocationRelativeTo(null);
pane = new Pane();
this.add(pane);
c = new ArrayList<Circle>();
SB = soundButton;
c.add(new Circle(20, 140));
c.add(new Circle(80, 140));
c.add(new Circle(140, 140));
c.add(new Circle(20, 80));
c.add(new Circle(80, 80));
c.add(new Circle(140, 80));
c.add(new Circle(20, 20));
c.add(new Circle(80, 20));
c.add(new Circle(140, 20));
this.setVisible(true);
}
public void init(){
pane.draw(c);
}
public void update(){
pane.draw(c);
keyManager.update();
if(keyManager.isNine()){
c.get(8).press();
SB.get(0).start();
}
else{
c.get(8).release();
SB.get(0).stop();
}
if(keyManager.isEight()){
c.get(7).press();
SB.get(1).start();
}
else{
c.get(7).release();
SB.get(1).stop();
}
if(keyManager.isSeven()){
c.get(6).press();
}
else{
c.get(6).release();
}
if(keyManager.isSix()){
c.get(5).press();
}
else{
c.get(5).release();
}
if(keyManager.isFive()){
c.get(4).press();
}
else{
c.get(4).release();
}
if(keyManager.isFour()){
c.get(3).press();
}
else{
c.get(3).release();
}
if(keyManager.isThree()){
c.get(2).press();
}
else{
c.get(2).release();
}
if(keyManager.isTwo()){
c.get(1).press();
}
else{
c.get(1).release();
}
if(keyManager.isOne()){
c.get(0).press();
}
else{
c.get(0).release();
}
}
public void run() {
init();
int fps = 60;
double timePerUpdate = 1000000000/fps;
double delta = 0;
long now;
long lastTime= System.nanoTime();
long timer = 0;
int updates = 0;
while(true){
now = System.nanoTime();
delta += (now - lastTime) / timePerUpdate;
timer+= now - lastTime;
lastTime = now;
if(delta >= 1){
update();
updates ++;
delta--;
}
if(timer >= 1000000000){
//System.out.println("Updates and Frames: "+ updates);
updates = 0;
timer = 0;
}
}
}
}
SoundButton:
public class SoundButton implements Runnable{
private AudioPlayer sound;
private boolean running = false;
private Thread thread;
public SoundButton(String path){
sound = new AudioPlayer(path);
}
@Override
public void run() {
}
public synchronized void start(){
if(running){
return;
}
else{
running = true;
thread = new Thread(this);
thread.start();
sound.play();
}
}
public synchronized void stop(){
if(!running)
return;
running = false;
sound.stop();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
发射器:
public class Launcher {
public static void main(String[] args){
ArrayList<SoundButton> SB = new ArrayList<SoundButton>();
SB.add(new SoundButton("/sound/sound1.mp3"));
SB.add(new SoundButton("/sound/sound2.mp3"));
Frame f = new Frame(SB);
Thread t = new Thread(f);
t.start();
}
}
如果需要,我的AudioPlayer类:
public class AudioPlayer
{
私人剪辑片段;
public AudioPlayer(String s)
{
try
{
AudioInputStream ais = AudioSystem.getAudioInputStream(
getClass().getResourceAsStream(s));
AudioFormat baseFormat = ais.getFormat();
AudioFormat decodeFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false
);
AudioInputStream dais = AudioSystem.getAudioInputStream(
decodeFormat, ais);
clip = AudioSystem.getClip();
clip.open(dais);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void play()
{
if (clip == null)
{
System.out.print("null");
return;
}
stop();
clip.setFramePosition(0);
clip.start();
System.out.println("Drain...");
clip.drain();
System.out.println("...Drained");
}
public void stop()
{
if (clip.isRunning())
{
clip.stop();
}
}
public void close()
{
stop();
clip.close();
}
}
答案 0 :(得分:0)
这是一个简单的修复,将SoundButton中start方法中的sound.play()移动到run方法而不是start方法。