# Audio Player: Fenster mit Play/Stop-Button erstellen, mit JSlider Lautstärke ändern



## xion63 (5. Jul 2010)

Hi,
ich will einen Clip Player mit einem Button erstellen. Es wird aber kein Fenster angezeigt und ich weiß nicht wieso. Ich höre immer nur den Clip. Die Buttons sind erstmal egal.

Habe in Zeile 31 ein JFrame erzeugt. Aber das funktioniert nicht.


Hier der komplette Code.


```
import java.awt.BorderLayout;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Control;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;

/**
 * Simple clip player that opens and starts an audio clip.
 */
public class SimpleClipPlayer extends Thread {
	/** Audio clip */
	Clip clip;
	
	
	/**
	 * Constructor which loads a given audio clip. 
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	public SimpleClipPlayer(URL clipFile, int nLoopCount) {
		
		JFrame f = new JFrame();
		f.setTitle("My Simple Clip Player");
		f.setSize(750,525);
		//f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLayout(new BorderLayout());

		
		
		loadAudioFile(clipFile, nLoopCount);
	}
	
	/**
	 * Loads an audio file from the Internet and plays it in a loop
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	private void loadAudioFile(URL clipFile, int nLoopCount) {
		
		try {			
			// create a stream from the file
			AudioInputStream stream = AudioSystem.getAudioInputStream(clipFile);

			// create info object
			DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
			
			// create and open clip
			clip = (Clip)AudioSystem.getLine(info);
			clip.open(stream);
			
			// print supported controls
			this.printSupportedControls();

			// set balance
			this.setPanOrBalance(+1);
			
			// tell the clip to loop
			clip.loop(nLoopCount);
			
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Prints a list of all supported controls to the command line
	 */
	private void printSupportedControls() {
		// get array of controls of the clip
		Control[] controls = clip.getControls();
		
		// print a list of all controls
		for (Control control : controls) {
			System.out.println(control.getType());
		}
	}
	
	/**
	 * Sets the balance or pan of the audio clip depending on the 
	 * control that is supported (pan for mono, balance for stereo).
	 * @param balance value from -1 (only left) to 1 (only right)
	 */
	private void setPanOrBalance(float balance) {
		// check if balance control is supported
		if(clip.isControlSupported(FloatControl.Type.BALANCE)) {
			
			// get balance control
			FloatControl balanceCtrl = (FloatControl)clip.getControl(FloatControl.Type.BALANCE);
				
			// adjust balance
			balanceCtrl.setValue(balance);
		}
		else {
			System.out.println("No balance control available!");
			// BALANCE control is only for stereo. 
			// The equivalent for mono is PAN, so try PAN:
			if(clip.isControlSupported(FloatControl.Type.PAN)) {

				// get balance control
				FloatControl panCtrl = (FloatControl)clip.getControl(FloatControl.Type.PAN);
					
				// adjust balance
				panCtrl.setValue(balance);
			}
			else {
				System.out.println("No pan control available!");
			}
		}	
	}
	
	/**
	 * Starts the clip and stops it after a given number of loops.
	 */
	public void run(){
		//clip.loop(Clip.LOOP_CONTINUOUSLY);
		
		// start the clip
		clip.start();
		
		// do nothing while clip is active
		while (clip.isActive()){}
		
		// stop the clip
		clip.stop();
	}
	
	/**
	 * Creates a new ClipPlayer object for a specific audio clip.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// define URL of the audio clip
			URL url = new URL(
					"http://freewavesamples.com/files/Alesis-Fusion-Bass-Loop.wav"); 
			
			// define the number of times the audio clip should be played 
			int nLoopCount = 3;
			
			// create a new clipPlayer object
			SimpleClipPlayer clipPlayer = new SimpleClipPlayer(url, nLoopCount);
			
			// start clip
	    	clipPlayer.start();
			
			/* 
			 * JSRessources: 
			 * In the JDK 5.0, the program would exit if we leave the main loop here. 
			 * This is because all Java Sound threads have been changed to be daemon threads, 
			 * not preventing the VM from exiting (this was not the case in 1.4.2 and earlier). 
			 * So we have to stay in a loop to prevent exiting here.
			 */
			while (true) {
				// sleep for 1 second.
				try {
					Thread.sleep(1000);
				}
				catch (InterruptedException e) {
					// Ignore the exception.
				}
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
}
```


Wäre dankbar wenn mir jemand erklärt wie ich hier ein Fenster erzeugen kann.


----------



## eRaaaa (5. Jul 2010)

```
f.setVisible(true);
```
 fehlt wohl!
siehe auch:
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 16.2 Fenster unter grafischen Oberflächen


----------



## xion63 (5. Jul 2010)

DANKE!!

Jetz hab ich nen Button erstellt. Beim anklicken soll der Clip abgespielt werden und wenn man ihn nochmal anklickt soll der Clip wieder stoppen. Das stoppen funktioniert, aber der Clip fängt automatisch an, ohne den Button anzuklicken.


```
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Control;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * Simple clip player that opens and starts an audio clip.
 */
public class SimpleClipPlayer extends Thread implements ActionListener {
	/** Audio clip */
	Clip clip;
	private JButton playstopButton;
	private JPanel panel_1;
	private boolean playstop = false;
	
	
	/**
	 * Constructor which loads a given audio clip. 
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	public SimpleClipPlayer(URL clipFile, int nLoopCount) {
		
		JFrame f = new JFrame();
		f.setTitle("My Simple Clip Player");
		f.setSize(750,525);
		//f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLayout(new BorderLayout());
		f.setVisible(true);
		
		
		//Panel erstellen
		panel_1 = new JPanel();
		panel_1.setLayout(new FlowLayout());
		f.add(panel_1);
		// Button erstellen
		playstopButton = new JButton("Play");
		panel_1.add(playstopButton);
		playstopButton.addActionListener(this);

		
		
		loadAudioFile(clipFile, nLoopCount);
	}
	
	/**
	 * Loads an audio file from the Internet and plays it in a loop
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	private void loadAudioFile(URL clipFile, int nLoopCount) {
		
		try {			
			// create a stream from the file
			AudioInputStream stream = AudioSystem.getAudioInputStream(clipFile);

			// create info object
			DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
			
			// create and open clip
			clip = (Clip)AudioSystem.getLine(info);
			clip.open(stream);
			
			// print supported controls
			this.printSupportedControls();

			// set balance
			this.setPanOrBalance(+1);
			
			// tell the clip to loop
			clip.loop(nLoopCount);
			
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Prints a list of all supported controls to the command line
	 */
	private void printSupportedControls() {
		// get array of controls of the clip
		Control[] controls = clip.getControls();
		
		// print a list of all controls
		for (Control control : controls) {
			System.out.println(control.getType());
		}
	}
	
	/**
	 * Sets the balance or pan of the audio clip depending on the 
	 * control that is supported (pan for mono, balance for stereo).
	 * @param balance value from -1 (only left) to 1 (only right)
	 */
	private void setPanOrBalance(float balance) {
		// check if balance control is supported
		if(clip.isControlSupported(FloatControl.Type.BALANCE)) {
			
			// get balance control
			FloatControl balanceCtrl = (FloatControl)clip.getControl(FloatControl.Type.BALANCE);
				
			// adjust balance
			balanceCtrl.setValue(balance);
		}
		else {
			System.out.println("No balance control available!");
			// BALANCE control is only for stereo. 
			// The equivalent for mono is PAN, so try PAN:
			if(clip.isControlSupported(FloatControl.Type.PAN)) {

				// get balance control
				FloatControl panCtrl = (FloatControl)clip.getControl(FloatControl.Type.PAN);
					
				// adjust balance
				panCtrl.setValue(balance);
			}
			else {
				System.out.println("No pan control available!");
			}
		}	
	}
	
	/**
	 * Starts the clip and stops it after a given number of loops.
	 */
/*	public void run(){
		//clip.loop(Clip.LOOP_CONTINUOUSLY);
		
		// start the clip
	//	clip.start();
		
		// do nothing while clip is active
	//	while (clip.isActive()){}
		
		// stop the clip
	//	clip.stop();
	}
	
	/**
	 * Creates a new ClipPlayer object for a specific audio clip.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// define URL of the audio clip
			URL url = new URL(
					"http://freewavesamples.com/files/Alesis-Fusion-Bass-Loop.wav"); 
			
			// define the number of times the audio clip should be played 
			int nLoopCount = 3;
			
			// create a new clipPlayer object
			SimpleClipPlayer clipPlayer = new SimpleClipPlayer(url, nLoopCount);
			
			// start clip
	//    	clipPlayer.start();
			
			/* 
			 * JSRessources: 
			 * In the JDK 5.0, the program would exit if we leave the main loop here. 
			 * This is because all Java Sound threads have been changed to be daemon threads, 
			 * not preventing the VM from exiting (this was not the case in 1.4.2 and earlier). 
			 * So we have to stay in a loop to prevent exiting here.
			 */
			while (true) {
				// sleep for 1 second.
				try {
					Thread.sleep(1000);
				}
				catch (InterruptedException e) {
					// Ignore the exception.
				}
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	
	
	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		if (cmd.equals("Play"))
		{
			if (playstop == false)
			{
				clip.start();	
				playstop = true;
			}
			else
			{
				clip.stop();
				playstop = false;
			}
		}
	}
	
	
	
}
```


----------



## eRaaaa (5. Jul 2010)

Liegt wohl am Aufruf:
[c] clip.loop(nLoopCount);[/c]

-->


> Starts looping playback from the current position.   Playback will
> continue to the loop's end point, then loop back to the loop start point
> <code>count</code> times, and finally continue playback to the end of
> the clip.[...]


----------



## xion63 (5. Jul 2010)

vom optischen bin ich jetzt schon mal ganz zufrieden. Aber wie kann ich die Lautstärke mit einem JSlider ändern. Und was ist der Unterschied zwischen MASTER_GAIN und VOLUME. Soweit ich das sehe ist MASTER_GAIN globaler. Müsste aber egal sein welches ich nehme.



```
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Dictionary;
import java.util.Hashtable;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Control;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Simple clip player that opens and starts an audio clip.
 */
public class SimpleClipPlayer extends Thread implements ActionListener, ChangeListener {
	/** Audio clip */
	Clip clip;
	private JButton playstopButton;
	private JPanel panel_1;
	private boolean playstop = false;
	
	
	/**
	 * Constructor which loads a given audio clip. 
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	public SimpleClipPlayer(URL clipFile, int nLoopCount) {
		
		JFrame f = new JFrame();
		f.setTitle("My Simple Clip Player");
		f.setSize(750,525);
		//f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLayout(new BorderLayout());
		f.setVisible(true);
		
		
		//Panel erstellen
		panel_1 = new JPanel();
		panel_1.setLayout(new FlowLayout());
		f.add(panel_1);
		
		// Button erstellen
		playstopButton = new JButton("Play");
		panel_1.add(playstopButton);
		playstopButton.addActionListener(this);
		
		// Slider für Sample Rate erstellen
		JSlider slider1;
		slider1 = new JSlider();
		slider1.setBorder(BorderFactory.createTitledBorder("Sample Rate"));
		slider1.setPaintTicks(true);
		slider1.setMajorTickSpacing(25);
		slider1.setMinorTickSpacing(5);
		slider1.setPaintLabels(true);
		Hashtable table = new Hashtable(); // Label überschreiben
		table.put(0, new JLabel("1/4")); 	// "0" mit "1/4" überschreiben
		table.put(25, new JLabel("1/2")); 	// "25" mit "1/2" überschreiben
		table.put(50, new JLabel("1"));		// "50" mit "1" überschreiben
		table.put(75, new JLabel("2"));		// "75" mit "2" überschreiben
		table.put(100, new JLabel("4"));	// "100" mit "4" überschreiben	
		slider1.setLabelTable(table);	
		slider1.addChangeListener(this);
		
		panel_1.add(slider1);		
			
		// Slider für Volume erstellen
		JSlider slider2;
		slider2 = new JSlider(0,100,25);
		slider2.setBorder(BorderFactory.createTitledBorder("Volume"));
		slider2.setPaintTicks(true);
		slider2.setMajorTickSpacing(50);
		slider2.setMinorTickSpacing(5);
		slider2.setPaintLabels(true);
		panel_1.add(slider2);
		
		

		
		
		loadAudioFile(clipFile, nLoopCount);
	}
	
	/**
	 * Loads an audio file from the Internet and plays it in a loop
	 * @param clipFile audio file
	 * @param nLoopCount number of times to loop
	 */
	private void loadAudioFile(URL clipFile, int nLoopCount) {
		
		try {			
			// create a stream from the file
			AudioInputStream stream = AudioSystem.getAudioInputStream(clipFile);

			// create info object
			DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
			
			// create and open clip
			clip = (Clip)AudioSystem.getLine(info);
			clip.open(stream);
			
			// print supported controls
			this.printSupportedControls();

			// set balance
			this.setPanOrBalance(+1);
			
			// tell the clip to loop
//			clip.loop(nLoopCount);
			
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Prints a list of all supported controls to the command line
	 */
	private void printSupportedControls() {
		// get array of controls of the clip
		Control[] controls = clip.getControls();
		
		// print a list of all controls
		for (Control control : controls) {
			System.out.println(control.getType());
		}
	}
	
	/**
	 * Sets the balance or pan of the audio clip depending on the 
	 * control that is supported (pan for mono, balance for stereo).
	 * @param balance value from -1 (only left) to 1 (only right)
	 */
	private void setPanOrBalance(float balance) {
		// check if balance control is supported
		if(clip.isControlSupported(FloatControl.Type.BALANCE)) {
			
			// get balance control
			FloatControl balanceCtrl = (FloatControl)clip.getControl(FloatControl.Type.BALANCE);
				
			// adjust balance
			balanceCtrl.setValue(balance);
		}
		else {
			System.out.println("No balance control available!");
			// BALANCE control is only for stereo. 
			// The equivalent for mono is PAN, so try PAN:
			if(clip.isControlSupported(FloatControl.Type.PAN)) {

				// get balance control
				FloatControl panCtrl = (FloatControl)clip.getControl(FloatControl.Type.PAN);
					
				// adjust balance
				panCtrl.setValue(balance);
			}
			else {
				System.out.println("No pan control available!");
			}
		}	
	}
	
	/**
	 * Starts the clip and stops it after a given number of loops.
	 */
/*	public void run(){
		//clip.loop(Clip.LOOP_CONTINUOUSLY);
		
		// start the clip
	//	clip.start();
		
		// do nothing while clip is active
	//	while (clip.isActive()){}
		
		// stop the clip
	//	clip.stop();
	}
	
	/**
	 * Creates a new ClipPlayer object for a specific audio clip.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// define URL of the audio clip
			URL url = new URL(
					"http://freewavesamples.com/files/Alesis-Fusion-Bass-Loop.wav"); 
			
			// define the number of times the audio clip should be played 
			int nLoopCount = 3;
			
			// create a new clipPlayer object
			SimpleClipPlayer clipPlayer = new SimpleClipPlayer(url, nLoopCount);
			
			// start clip
	//    	clipPlayer.start();
			
			/* 
			 * JSRessources: 
			 * In the JDK 5.0, the program would exit if we leave the main loop here. 
			 * This is because all Java Sound threads have been changed to be daemon threads, 
			 * not preventing the VM from exiting (this was not the case in 1.4.2 and earlier). 
			 * So we have to stay in a loop to prevent exiting here.
			 */
			while (true) {
				// sleep for 1 second.
				try {
					Thread.sleep(1000);
				}
				catch (InterruptedException e) {
					// Ignore the exception.
				}
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	
	
	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		if (cmd.equals("Play"))
		{
			if (playstop == false)
			{
				clip.start();	
				clip.loop(Clip.LOOP_CONTINUOUSLY);
				playstop = true;
			}
			else
			{
				clip.stop();
				playstop = false;
			}
		}
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		// TODO Auto-generated method stub
		SourceDataLine line;
		FloatControl control = (FloatControl) line.getControl(FloatControl.Type.VOLUME);
		control.setValue(slider2);
		
	}
	
	
	
}
```


wär für einen kleinen Tipp dankbar


----------



## eRaaaa (5. Jul 2010)

Ok, erstmal ein paar allgemeine Dinge:

- Wenn du willst das Slider2 das Volume regelt und somit auch stateChanged benutzt, musst du natürlich den Listener auch an slider2 registrieren, nicht an slider1 

- wenn du in stateChanged auf slider2 zugreifen möchtest, solltest du slider2 nicht als lokale Variable im Konsturktor deklarieren...(oder eben in stateChanged nicht auf slider2 versuchen zuzugreifen, sondern  e.getSource() )

- setVisible(true) am Besten immer zum Schluss aufrufen(nachdem alle Komponenten hinzugefügt wurden etc.)


So jetzt zum stateCHanged bzw. zu deinem volume-Problem:

Wirklich eine große Hilfe bin ich da jetzt nicht, da ich noch nie wirklich mit diesen Audioclips gearbeitet habe, aber ich meine mich erinnern zu können, das man da ein wenig umrechnen muss, d.h. setValue(100) ist nicht gleich 100% usw..wie genau das geht findest du aber sicherlich hier im Forum, was ich aber auf jeden Fall sagen kann ist, dass das so schon mal nicht gehen kann. "line" kommt ja nicht aus dem Himmel angeflogen und initialisiert sich da einfach *g*
Wahrscheinlich eher so etwas:

```
FloatControl control = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        control.setValue(slider2.getValue());
```

wobei wie ich schon sagte höchstwahrscheinlich Probleme geben wird mit dem Wertebereich!
Einfahc mal diesbezüglich die Forensuche benutzen...


----------



## xion63 (12. Jul 2010)

jetzt funktioniert alles

DANKE!


----------

