2016-04-29 85 views
0

在线查看后,我发现一个类的简单示例,显示三个左右线程同时工作。但我似乎无法将其纳入我的计划。我正在制作一个利用数字键盘上的按键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 

{
private clip clip;

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

这是一个简单的解决,在SoundButton移动sound.play()中的开始的方法来运行方法,而不是在开始方法。