单击不同的按钮时如何播放多个WAV文件? [英] How to play multiple WAV files when different buttons are clicked?

查看:65
本文介绍了单击不同的按钮时如何播放多个WAV文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java创建一个简单的音频拨号程序.我已经完成了按钮及其功能的设置,就像在文本字段中显示它一样.我只是不知道如何在单击时让我的按钮发出声音.一旦按下拨号"(例如,当您呼叫某人时),我还需要它们播放所有数字的音调.我有大约12个WAV文件用于音调,这是到目前为止我关于框架的代码(不是Driver类).

I am creating a simple tone dialer in Java. I am done putting up the buttons and their functionalities as in displaying it in the text field and all that. I just don't know how to get my buttons to make tones when clicked. I also need them to play all the numbers' tones once "Dial" is pressed (like when you call someone). I have about 12 WAV files for the tones and this is my code for the frame so far (not Driver class).

public class dialerFrame extends JFrame
{
    private JTextField display;// creating text field display
    private static final int FRAME_WIDTH = 500;// frame width
    private static final int FRAME_HEIGHT = 500;// frame height
    private JButton numButton, clrButton, backButton, dialButton;//creating all buttons needed

    /**
     * Constructor to build frame
     */
    public dialerFrame()
    {
        display = new JTextField ("");//setting text field to empty 
        display.setEditable(false);//setting text field to not take in values
        add(display, BorderLayout.NORTH);//assigning north region for the text field and adding to frame
        createNumButtonPanel();
        createOperatorButtonPanel();
        setSize(FRAME_WIDTH, FRAME_HEIGHT);//
    }

    /**
     * Method to construct all numeric buttons from 1-9 and set layout
     */
    private void createNumButtonPanel()
    {
        JPanel numButtonPanel = new JPanel();// creating a panel for numbers and symbols only
        numButtonPanel.setLayout(new GridLayout(4,3));//setting 4 by 3 grid layout for the panel

        //adding the buttons on the panel
        numButtonPanel.add(makeDigitButton("1"));
        numButtonPanel.add(makeDigitButton("2"));
        numButtonPanel.add(makeDigitButton("3"));
        numButtonPanel.add(makeDigitButton("4"));
        numButtonPanel.add(makeDigitButton("5"));
        numButtonPanel.add(makeDigitButton("6"));
        numButtonPanel.add(makeDigitButton("7"));
        numButtonPanel.add(makeDigitButton("8"));
        numButtonPanel.add(makeDigitButton("9"));
        numButtonPanel.add(makeDigitButton("*"));
        numButtonPanel.add(makeDigitButton("0"));
        numButtonPanel.add(makeDigitButton("#"));

        add(numButtonPanel, BorderLayout.CENTER);//adding panel to frame in the center
    }

    /**
     * Method to construct operator buttons and assign their function separately 
     */
    private void createOperatorButtonPanel()
    {
        JPanel operatorButtonPanel = new JPanel(new GridLayout(1,3));//creating panel for the operator buttons
        OperatorButtonListener listener = new OperatorButtonListener();// listener for operator buttons
        //creating operator buttons and assigning action listener 
        clrButton = new JButton("CLR");
        clrButton.addActionListener(listener);
        backButton = new JButton("BACK");
        backButton.addActionListener(listener);
        dialButton = new JButton("DIAL");
        dialButton.addActionListener(listener);

        //adding operator buttons to panel
        operatorButtonPanel.add(clrButton);
        operatorButtonPanel.add(backButton);
        operatorButtonPanel.add(dialButton);

        //adding panel to frame in the south region
        add(operatorButtonPanel, BorderLayout.SOUTH);
    }

    /**
     * Inner class listener for the numeric buttons
     */
    private class DigitButtonListener implements ActionListener
    {
        private String digit;

         public DigitButtonListener(String digit)
         {
             this.digit = digit;
         }

         /**
          * Overriding actionPerformed method to be used by the numeric buttons
          */
         public void actionPerformed(ActionEvent event) 
         {
             display.setText(display.getText() + digit);//displaying the corresponding digit on the text field
         }
    }

    /**
     *Inner class listener for operator buttons
     */
    private class OperatorButtonListener implements ActionListener
    {
        /**
        * Overriding actionPerformed method to be used for by the operator Button
        */
        public void actionPerformed (ActionEvent event)
        {
            if(event.getSource() == backButton)
            {
                display.setText(""+display.getText().substring(0, display.getText ().length() - 1));// remove last character
            }
            if(event.getSource() == clrButton)
            {
                display.setText("");// clear text field
            }
            if(event.getSource() == dialButton)
            {

            }
        }
    }

    /**
     * Makes a button representing a digit of the dialer.
     * @param digit takes in digit for dialer 
     * @return numButton the respective button of the dialer
     */
    public JButton makeDigitButton(String digit)
    {
        numButton = new JButton(digit);
        ActionListener listener = new DigitButtonListener(digit);
        numButton.addActionListener (listener);
        return numButton;
    }
}

推荐答案

IDK有点棘手,您对多线程的经验也是如此.

It's a little tricky and IDK how experienced you are with multi-threading.

首先,我将尝试使用MVC模式.您已经设置了 View 部分的基础知识.对于 Model ,也许enum类对于电话号码的每个号码都有意义,其中每个enum与一个ID相关联,一个String用于显示,以及一个相关联的Clip (预加载)或.wav文件地址(如果使用SourceDataLine),并且可能是一种播放方法.

First off, I would try to use an MVC pattern. You've got the basics of your View portion set up. For the Model, perhaps an enum class makes sense for each number of the phone number, where each enum is associated with an ID, a String for display and an associated Clip (preloaded) or .wav file address (if using SourceDataLine), and maybe a play method.

然后,关键的Control功能是可能在自己的线程中连续播放电话号码,这样您才不会死在水中等待声音播放完毕.

Then, a critical Control capability is the playback of the phone number, in series, probably within its own thread so that you aren't dead in the water waiting for the sounds to finish playing.

我将使该控制器成为一个类,并使其实现LineListener并使其对Line.EventType.STOP做出响应(可能只是为松耦合方法设置了状态标志/布尔值),作为管理排序的一种方式ClipSourceDataLine播放的时间和时间. (@camickr在评论中提到了这一点)

I'd make this controller a class, and have it implement a LineListener and have it respond to Line.EventType.STOP (probably just set a state flag/boolean for a loosely coupled approach) as a way to manage the sequencing and timing of the individual Clip or SourceDataLine plays. (@camickr mentions this in a comment)

我还将启动在其自己的线程中执行电话号码播放的部分.它可以是控制器类中的私有类,因此可以引用LineListener的父类的实现来检查何时继续播放下一个"声音.

I'd also launch the portion that executes the playing of the phone number in its own thread. It can be a private class within the controller class, and thus make reference to the parent class's implementation of the LineListener to check for when to proceed for the "next" sound.

这是基本的平面图.还有一些细节尚待解决,但是希望这会帮助您前进.

That's the basic floor-plan. There are some details to work out still, but hopefully this will help get you going.

这篇关于单击不同的按钮时如何播放多个WAV文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆