1

I am trying to program an applet that has four buttons, all of which play a short audio file. The goal is to try and have the user successfully click the buttons any number of times, therefore creating a beat. Here is my attempt:

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;


public class drumKit extends JApplet
{

    private JButton snareButton;
    private JButton hiHatButton;
    private JButton bassButton;
    private JButton cymbalsButton;
    private AudioClip snare;
    private AudioClip hiHat;
    private AudioClip bass;
    private AudioClip cymbals;

    public void init()
    {
        setLayout (new FlowLayout());

        sampleButtons();

        snare = getAudioClip(getDocumentBase(), "Snare.wav");
        hiHat = getAudioClip(getDocumentBase(), "HiHat.wav");
        bass = getAudioClip(getDocumentBase(), "Kick.wav");
        cymbals = getAudioClip(getDocumentBase(), "Crash.wav");

    }

    private void sampleButtons()
    {
        snareButton = new JButton("Snare");
        hiHatButton = new JButton("Hi Hat");
        bassButton = new JButton("Kick");
        cymbalsButton = new JButton("Cymbals");

        snareButton.addActionListener(new ButtonListener());
        hiHatButton.addActionListener(new ButtonListener());
        bassButton.addActionListener(new ButtonListener());
        cymbalsButton.addActionListener(new ButtonListener());

        add(snareButton);
        add(hiHatButton);
        add(bassButton);
        add(cymbalsButton);
    }

    private class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if (e.getSource() == snareButton)
                snare.play();
            if (e.getSource() == hiHatButton)
                hiHat.play();
            if (e.getSource() == bassButton)
                bass.play();
            if (e.getSource() == cymbalsButton)
                cymbals.play();



        }
    }
}

The problem is, when I click the buttons, nothing plays. I referred to the solutions listed here, a window pops up preventing any further interactions with the applet. Sorry, a bit of a newbie here. //Thanks for your help.

Community
  • 1
  • 1
  • You can't read a file from disk in an applet. It must be on the server--which means you need to be running a server which can serve up these files. – Jared May 10 '14 at 00:34
  • Also, this class should be a `JPanel`, not a `JApplet`. To create an applet, you should just call `this.setContentPane(new YourPanel())` in a class which extends `JApplet`'s `init()` method. You can also create a standalone application by creating a `JFrame` in a `main` method and then set _its_ content pane to your panel. – Jared May 10 '14 at 00:42
  • 1
    Why code an applet? If it is due to spec. by teacher, please refer them to [Why CS teachers should stop teaching Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). 3) Note that this code is not using java sound at any point, but the applet based `AudioClip`. See the [info. page for Java Sound](stackoverflow.com/tags/javasound/info) for a better way to play a `Clip` from an `URL`. – Andrew Thompson May 10 '14 at 07:36
  • thank you both for your replies. Andrew, yes, it is because of teacher spec. The professor gave us the option of an Applet or a GUI. How would you go about changing this program to a GUI? – user3618886 May 10 '14 at 17:22
  • I'm curious about this teacher because Java Sound is _not_ an easy topic--it took me a few years to finally penetrate the Java sound library--it's not (in my opinion) an easy topic. – Jared May 12 '14 at 07:31

1 Answers1

0

When you say "applet or GUI" I think you really mean applet or application--they are both GUIs. I'm not really familiar with AudioClip, but if it works as easy as it seems, then all you need to do is change your JApplet to a JPanel, then create a main method which creates a JFrame and set its content pane to your JPanel:

disclaimer: This code has not been tested and probably contains complilation errors (I will correct anything pointed out).

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;


public class drumKit extends JPanel implements ActionListener
{

    private final JButton snareButton;
    private final JButton hiHatButton;
    private final JButton bassButton;
    private final JButton cymbalsButton;
    private final AudioClip snare;
    private final AudioClip hiHat;
    private final AudioClip bass;
    private final AudioClip cymbals;

    public drumKit()
    {
        super();

        // create buttons
        snareButton = new JButton("Snare");
        hiHatButton = new JButton("Hi Hat");
        bassButton = new JButton("Kick");
        cymbalsButton = new JButton("Cymbals");

        // setup audio clips
        snare = getAudioClip(getDocumentBase(), "Snare.wav");
        hiHat = getAudioClip(getDocumentBase(), "HiHat.wav");
        bass = getAudioClip(getDocumentBase(), "Kick.wav");
        cymbals = getAudioClip(getDocumentBase(), "Crash.wav");

        // set layout
        setLayout (new FlowLayout());

        // add this action listener to the buttons and add to this panel
        sampleButtons();
    }

    private void sampleButtons()
    {
        // add this as the each button's action listener
        snareButton.addActionListener(this);
        hiHatButton.addActionListener(this);
        bassButton.addActionListener(this);
        cymbalsButton.addActionListener(this);

        // add each button to this panel
        this.add(snareButton);
        this.add(hiHatButton);
        this.add(bassButton);
        this.add(cymbalsButton);
    }

    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == snareButton)
            snare.play();
        else if (e.getSource() == hiHatButton)
            hiHat.play();
        else if (e.getSource() == bassButton)
            bass.play();
        else if (e.getSource() == cymbalsButton)
            cymbals.play();
    }

    /**
     * main method creates a frame which contains this custom panel
     * and displays it.
     */
    public static void main(String ...args){
        // set the look and feel to the system's look and feel
        try{
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e){
            // if this fails, who cares, the look and feel will be Java's
            // just continue
        }

        // create frame and make sure that when you close the frame the 
        //    program exits!
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create your panel, set it to the frame's content pane, 
        //    then show the frame
        final JPanel panel = new drumKit();
        frame.setContentPane(panel);
        frame.setVisible(true);

        // resize the frame to be the preferred size of your panel
        frame.pack();
}

If you cannot read the files, then I would suggest putting in the fully qualified path name rather than just "Snare.wav" (for example) which looks in the current CLASSPATH directory (which for eclipse, I believe is the project directory).

Jared
  • 940
  • 5
  • 9
  • Jared, thank you so much for taking the time out of your day to edit the program. I really appreciate it. When I try to run your version, it says getDocumentBase is undefined which I don't understand because we imported the Applet class. Any idea why this is? – user3618886 May 11 '14 at 23:12
  • @user3618886 So `getDocumentBase()` is a method from `Applet` (a non-static method) which gets the URL of the applet. I don't think `AudioClip` is going to work with an application. You may need to use [Clip](http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/Clip.html) instead (which is more involved). I would suggest reading [Playing Back Audio](http://docs.oracle.com/javase/tutorial/sound/playing.html) – Jared May 12 '14 at 04:33
  • @user3618886 Actually, the more I read about Java sound the more I think what you want is going to be difficult to implement. For simplicity, I almost want to go back to your original applet design (using `AudioClip`)...the problem is that you need a server to serve up the audio files. There is likely a way to modify the SecurityManager such that it allows reading the disk, but I think that's very bad practice. Do you know anything about J2EE projects? You can create a webserver with something like Tomcat and then serve up the files with that. – Jared May 12 '14 at 07:41