Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
192 views
in Technique[技术] by (71.8m points)

java - How to play multiple WAV files when different buttons are clicked?

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;
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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.

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.

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)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...