Java - 如何从另一个类停止audioclip

时间:2014-10-07 12:19:57

标签: java audio

现在,我正在制作一个涉及背景音频的应用程序,并且通过其他问题和答案中的一些提示,我能够使音频工作。

但是现在,我正在尝试使用不同类中的按钮来停止在另一个类中实例化的音频文件夹。

当我测试原型时,所有都在同一个类中,它完美地工作。

但在我的主应用程序中,“停止”按钮位于不同的类中(有充分理由)。我不知道你是否想要我的主要应用程序的代码,但这里是我描述的原型:任何帮助将不胜感激,谢谢。

public class AudioPlay  {

    Clip clip;

   // Constructor
   public AudioPlay() {
        try {
            this.clip = AudioSystem.getClip();
        } catch (LineUnavailableException ex) {
            Logger.getLogger(AudioPlay.class.getName()).log(Level.SEVERE, null, ex);
        }

       JFrame f = new JFrame();

      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setTitle("Test Sound Clip");
      f.setSize(300, 200);
      f.setLayout(new FlowLayout());

      JButton button = new JButton("play");
        button.addActionListener(new  ActionListener() {
           public void actionPerformed(ActionEvent e) {                    
             playSound(0);                                     
           }
        });            

        JButton button2 = new JButton("stop");
        button2.addActionListener(new  ActionListener() {
           public void actionPerformed(ActionEvent e) {
                clip.stop();                          
           }
        });

        f.add(button);
        f.add(button2);
        f.setVisible(true);

   }

   public void playSound(int a){

       // Open an audio input stream.
       String[] sounds = new String[10];
       sounds[0]= "/audioplay/sounds/kk.wav";
       sounds[1]= "/audioplay/sounds/btn2.wav";
       try {
         URL url = this.getClass().getResource(sounds[a]);
         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);

         // Open audio clip and load samples from the audio input stream.
         clip.open(audioIn);
         clip.start();            

      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }

}

   public static void main(String[] args) {
       new AudioPlay();
   }
}

EDIT 这是实际的应用程序 首先是主要类.............

public class Operator {
     static boolean player = false;
     Clip clip;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        // TODO code application logic here
        Welcome on = new Welcome();
        on.setLocationRelativeTo(null);
        on.setVisible(true);


    }

    public Operator() {
         try {
             this.clip = AudioSystem.getClip();
         } catch (LineUnavailableException ex) {
             Logger.getLogger(Operator.class.getName()).log(Level.SEVERE, null, ex);
         }

    }


     public void playBackground(int a){
    String[] sounds = new String[10];
       sounds[0]= "/operator/sounds/kk.wav";
       sounds[1]= "/operator/sounds/mnt5.wav";

      try {
         // Open an audio input stream.
          URL url= this.getClass().getResource(sounds[a]);

         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
         // Get a sound clip resource.

         // Open audio clip and load samples from the audio input stream.
         clip.open(audioIn);
         clip.start();
      } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
      }
    }

    }

现在接下来,是声音开始播放的地方

public class MainMenuTest extends javax.swing.JPanel {

   // this is for referencing 
    Operator sound = new Operator();
     static int course;
     static String courseName;

    //constructor  obviously..........
    public MainMenuTest() {

        initComponents();
    }





    public javax.swing.JPanel jPanel1;


    @SuppressWarnings("unchecked")

    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();



        sound.playBackground(0);
    /* writing this stop() action here below, causes the audio not to play, which is actually 
        what i want, but in another class 
        sound.clip.stop();
*/
        //most of the components are removed, they weren't really relevant


    }                                      


}

最后,剪辑停止的类

public final class Options extends JPanel {
    // referencing stuff
    Operator sound = new Operator();
     private JButton Start;


    public Options() {
        initComponents();

    }


    @SuppressWarnings("unchecked")

    private void initComponents() {


        Stop = new javax.swing.JButton("stop");



     Stop.addActionListener(new  ActionListener() {
      public void stopActionPerformed(ActionEvent e) {
           //this looks like the same stop() method  wrote before, but here, it ain't working
            sound.clip.stop();      


    }});                                    

    }                                           





}

1 个答案:

答案 0 :(得分:2)

正如猜测的那样,从评论中你制作了额外的新对象。制作一个新对象就像拥有一个双胞胎。告诉一对双胞胎停止说话不会影响另一方......

操作员声音=新操作员(); //在你的代码中,这应该只进行一次。

仅在主mehtod中执行此操作,并在构造函数中使用其他类来接受此操作或使用spring或其他依赖注入。

一个简单的样本:

package play;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JButton;
import javax.swing.JFrame;

public class AudioPlay  {

    private Clip clip;
    JFrame f = new JFrame();
   // Constructor
   public AudioPlay() {
        try {
            this.clip = AudioSystem.getClip();
        } catch (LineUnavailableException ex) {
            Logger.getLogger(AudioPlay.class.getName()).log(Level.SEVERE, null, ex);
        }



      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setTitle("Test Sound Clip");
      f.setSize(300, 200);
      f.setLayout(new FlowLayout());

      JButton button = new JButton("play");
        button.addActionListener(new  ActionListener() {
           public void actionPerformed(ActionEvent e) {                    
             playSound(0);                                     
           }
        });            



        f.add(button);

        //f.setVisible(true);

   }

   public void stopSound() {
        clip.stop();   
        //clip.flush();
        clip.close();

    }

   public void playSound(int a){

       // Open an audio input stream.
       String[] sounds = new String[10];
       sounds[0]= "rs/Tr-3L_nA_sus_mf_D4.wav";
       sounds[1]= "rs/Tr-3L_nA_sus_mf_F#4.wav";
       File f = new File(sounds[a]);
       try {
         URL url = f.toURI().toURL();
         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);

         // Open audio clip and load samples from the audio input stream.
         clip.open(audioIn);
         clip.start();            

      } catch (Exception e) {
         e.printStackTrace();
         System.out.println(e + " " + f);
      }

}

   public static void main(String[] args) {
       AudioPlay ap = new AudioPlay();
       Other oth = new Other(ap, ap.f);
       ap.shw();
   }

   public void shw(){
       f.setVisible(true);
   }
}

//和

package play;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Other {

    private AudioPlay au;
    private JButton btnStop;

    public Other(AudioPlay aupl, JFrame f){
        this.au = aupl;
        btnStop = new JButton("Stop");
        f.add(btnStop);
        btnStop.addActionListener(new  ActionListener() {
           public void actionPerformed(ActionEvent e) {
                au.stopSound();                       
           }


        });
    }

}

这里看看Other如何接受对音频播放类的引用。音频播放课程只制作一次(新)。

仅供参考:不适用于此但一般情况下:如果我们需要旧物品或者旧物品是关于其他物品,我们确实想要制作新物品。示例数据传输对象,其中一个是关于id = 1且另一个具有标识2的实体,我们在hashmap或其他集合中跟踪它们。

同样在网络应用中,我们有会话,请求范围 - 但这超出了这个范例。对于此示例,主要的是在UI中我们通常只需要每个类的一个实例,并且不同的类需要相同的实例进行通信。在与实例2进行对话时,一个类不能与实例1交谈,并期望实例1做某事。