java - 当我按下几个 Jbuttons 时无法播放多个声音

标签 java swing audio jbutton javasound

我的 java 程序中有三个按钮,可以播放三种不同的声音。看看我的代码:

    import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.*;
import java.awt.datatransfer.*;

public class VueEditeurEmail extends JFrame implements ActionListener {

    private JPanel container = new JPanel();
    private JPanel containerHaut = new JPanel();
    private JPanel containerAction = new JPanel();
    private JButton boutonEnvoyer = new JButton("Envoi");
    private JButton boutonAnnuler = new JButton("Annuler");
    private JButton contacts = new JButton("Contacts");
    private JButton coller = new JButton("Coller");
    private JTextArea textArea = new JTextArea();
    private ChampsTexte champs1 = new ChampsTexte("Expéditeur :", "");
    private ChampsTexte champs2 = new ChampsTexte("Destinataire :", "");
    private ChampsTexte champs3 = new ChampsTexte("Objet :", "");
    private JOptionPane jop1 = new JOptionPane();
    private JOptionPane jop2 = new JOptionPane();
    private JOptionPane jop3 = new JOptionPane();
    final Clipboard clipboard = container.getToolkit().getSystemClipboard();


    public VueEditeurEmail() {
        this.setTitle("Expéditeur de Message");
        this.setSize(500, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        containerHaut.setLayout(new BoxLayout(containerHaut, BoxLayout.Y_AXIS));
        containerHaut.add(champs1);
        containerHaut.add(champs2);
        containerHaut.add(contacts);
        containerHaut.add(coller);
        containerHaut.add(champs3);

        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);

        JScrollPane scrollPan = new JScrollPane(textArea);

        container.setLayout(new BorderLayout());
        container.setBackground(Color.white);
        container.add(containerHaut, BorderLayout.NORTH);
        container.add(scrollPan, BorderLayout.CENTER);

        container.add(containerAction, BorderLayout.SOUTH);
        containerAction.add(boutonEnvoyer, BorderLayout.EAST);
        containerAction.add(boutonAnnuler, BorderLayout.WEST);

        contacts.addActionListener(this);
        boutonEnvoyer.addActionListener(this);
        boutonAnnuler.addActionListener(this);
        coller.addActionListener(this);

        this.setContentPane(container);
        this.setVisible(true);

        containerHaut.setBackground(Color.GRAY);
        champs1.setBackground(Color.GRAY);
        champs2.setBackground(Color.GRAY);
        champs3.setBackground(Color.GRAY);
        textArea.setBackground(Color.YELLOW);
        boutonEnvoyer.setBackground(Color.GRAY);
        boutonAnnuler.setBackground(Color.GRAY);

    }

        public void playSound(String soundName){
            try{
                AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(soundName).getAbsoluteFile( ));
                Clip clip = AudioSystem.getClip( );
                clip.open(audioInputStream);
                clip.start( );
            }catch(Exception ex){
                System.out.println("Erreur lors de la lecture du son");
                ex.printStackTrace( );
            }
        }

    public void actionPerformed(ActionEvent E) {

        if(E.getSource() == boutonEnvoyer){
            playSound("Envoyé.wav");
            Email monEmail = new Email(champs1.getTexte(), champs2.getTexte(), champs3.getTexte(), textArea.getText());
            monEmail.EnvoiSMTP("admpcsrv1.uha.fr", 25);


            ImageIcon img1 = new ImageIcon("Images/succès.png");
            jop1.showMessageDialog(null, "L'Email a bien été envoyé", "Envoi réussi", JOptionPane.INFORMATION_MESSAGE, img1);
            System.exit(0);
        }

        else if(E.getSource() == boutonAnnuler){
            playSound("Annulé.wav");
            ImageIcon img2 = new ImageIcon("Images/annuler.png");
            jop2.showMessageDialog(null, "Appuyer sur OK pour confirmer l'annulation", "Annulation", JOptionPane.INFORMATION_MESSAGE, img2);
            System.exit(0);
        }

        else if (E.getSource() == contacts){
            playSound("OuvertureContacts.wav");
            ImageIcon img3 = new ImageIcon("Images/OuvertureContacts.png");
            jop3.showMessageDialog(null, "Ouverture de la liste des contacts, appuyer sur Ok pour fermer ce popup", "Liste des contacts", JOptionPane.INFORMATION_MESSAGE, img3);
            File file = new File("Fichiers/InfosContacts.xls");
            try{
            Desktop.getDesktop().open(file);
            }catch(IOException e){
            System.out.println("Ouverture du fichier impossible");
            }

        }

        else if (E.getSource() == coller){
            Transferable clipData = clipboard.getContents(clipboard);
            try{
                if(clipData.isDataFlavorSupported(DataFlavor.stringFlavor)){
                String s = (String)(clipData.getTransferData(DataFlavor.stringFlavor));
                champs2.fieldTexte.replaceSelection(s);
                }
            }catch(Exception ufe){}
        }

    }

    public static void main(String[] args) {
        VueEditeurEmail monEditeur = new VueEditeurEmail();

    }
}

当我按下“联系人”按钮时,声音“OuvertureContacts.wav”播放得很好。但是之后,当我按下“boutonEnvoyer”按钮或“boutonAnnuler”按钮时,他们的声音没有播放......问题是什么,我对三个按钮使用相同的代码但是当我按下一个按钮时,另一个没有'在第一次按下后播放声音!

非常感谢您的帮助,提前致谢!

最佳答案

您的片段提出了几个问题:

  • Swing GUI 对象应该event dispatch thread 上构造和操作.

  • 为每个不同的声音提供自己的流和剪辑;每个剪辑只初始化一次,而不是每次播放剪辑时都初始化。

    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(…);
    Clip clip = AudioSystem.getClip( );
    clip.open(audioInputStream);
    
  • 尽管音频系统在单独的线程中播放剪辑,您可能希望在单独的线程中定位和start() 剪辑;这将最大限度地减少 EDT 上的延迟并增强 active

    private void playSound() {
        Runnable soundPlayer = new Runnable() {
    
            @Override
            public void run() {
                try {
                    clip.setMicrosecondPosition(0);
                    clip.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(soundPlayer).start();
    }
    
  • 另见 标签 info和这个相关的example .

附录:SSCCE

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;

/**
 * @see https://stackoverflow.com/a/17130160/230513
 * @see http://pscode.org/media/
 * @see http://www.soundjay.com/beep-sounds-1.html
 */
public class Test {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new FlowLayout());
        f.add(new JButton(new SoundAction("Play 1",
            "http://pscode.org/media/leftright.wav")));
        f.add(new JButton(new SoundAction("Play 2",
            "http://www.soundjay.com/button/beep-1.wav")));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    class SoundAction extends AbstractAction {

        private Clip clip;

        public SoundAction(String name, String location) {
            super(name);
            try {
                URL url = new URL(location);
                AudioInputStream ais = AudioSystem.getAudioInputStream(url);
                clip = AudioSystem.getClip();
                clip.open(ais);
            } catch (Exception e) {
                e.printStackTrace(System.err);
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // Runnable optional
            Runnable soundPlayer = new Runnable() {
                @Override
                public void run() {
                    try {
                        clip.setMicrosecondPosition(0);
                        clip.start();
                    } catch (Exception e) {
                        e.printStackTrace(System.err);
                    }
                }
            };
            new Thread(soundPlayer).start();
        }
    }
}

关于java - 当我按下几个 Jbuttons 时无法播放多个声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17129019/

相关文章:

java - 无法使用 Scanner 类,构造函数未定义,方法未定义

java - 使用 Jackson 转换为 JSON 时处理空 XML 节点

java - 带有 JOptionPane 的 ImageIcon 未出现在可执行 JAR 中

javascript - 当我单击div框时,音频无法播放

audio - 谷歌主页 Action 播放/继续,前进/后退

Java 设计问题 : Enforce method call sequence

java - Android Drive API OAuth BAD_AUTHENTICATION

java - 使用 MySQL 中的数据填充 JComboBox

java - 将 JFrame 转换为 JPanel

bash - 如何在没有GUI的情况下通过Debian中的Bash用VLC流式传输音频?