Nullpointer bei Wertübergabe

Status
Nicht offen für weitere Antworten.

Antoras

Top Contributor
Hallo,

ich hab mir ein kleines Programm geschrieben, das einen Audiostream (z.B. per Mikrofon) aufnehmen und danach wieder abspielen kann.

Das Programm funktioniert - wenn ich innere Klassen verwende. Sobald ich aber mehrere "normale" Klassen nehme (nennt man die alle äußere Klassen oder haben die nochmal eine eigene Bezeichnung) bekomme ich Probleme mit der Wertübergabe. Momentan ist es so, dass ich auf Methoden/Attribute einer anderen Klasse zugreife, indem ich deren Instanz vor den Befehl schreibe.
Beispiel:
Code:
private Sound sound = new Sound();
	
sound.audioInputStream.read();

Beim Programmaufruf bekomme ich jedoch einen NullPointer. Ist ja klar, Sound ist ja null. Aber wie stell ich das jetzt aber am geschicktesten an, damit das Programm trotzdem funktioniert? Ist diese von mir oben gezeigte Instanziierung überhaupt sinnvoll, oder gibt es da einen besseren Weg die Klassen untereinander kommunizieren zu lassen?

Wäre schön wenn mir hier jemand weiterhelfen könnte.

Das komplette Projekt: antoras.de/programmierung/sound.rar

Teile des Codes:
Code:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;


/**
 * This class manage the audio data
 * @author antoras
 * 
 */
public class Sound /* extends SoundAdministration */{
	
	protected boolean stopCapture = false;
	
	//Listen the binary data
	protected ByteArrayOutputStream byteArrayOutputStream;
	//Set important parameters
	protected AudioFormat audioFormat;
	//Can read the audio data
	protected TargetDataLine targetDataLine;
	//Stream with an specific audio format
	protected AudioInputStream audioInputStream;
	//Audio byte line
	protected SourceDataLine sourceDataLine;	
	
	/**
	 * Capture audio data in a thread. Otherwise it is difficult to
	 * do other things
	 */
	public void captureAudio() {
		try {
			audioFormat = getAudioFormat();
			DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
			targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
			targetDataLine.open(audioFormat);
			targetDataLine.start();
			
			Thread captureThread = new Thread(new CaptureThread());
			captureThread.start();
			
		} catch (Exception e) {
			System.out.println(e);
			System.exit(0);
		}
	}

	/**
	 * Play back the audio data in a thread. Otherwise it is difficult to
	 * do other things
	 */
	public void playAudio() {
		try {
			byte audioData[] = byteArrayOutputStream.toByteArray();
			InputStream byteArrayInputStream = new ByteArrayInputStream(audioData);
			AudioFormat audioFormat = getAudioFormat();
			audioInputStream = new AudioInputStream(byteArrayInputStream, audioFormat,
					audioData.length/audioFormat.getFrameSize());
			DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
			sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
			sourceDataLine.open(audioFormat);
			sourceDataLine.start();
			
			Thread playThread = new Thread(new PlayThread());
			playThread.start();
			
		} catch (Exception e) {
			System.out.println(e);
			System.exit(0);
		}
	}
	
	/** 
	 * There can be problems without/wrong parameters of the AudioFormat
	 * @return 
	 */
	public AudioFormat getAudioFormat() {
		//8000, 11025, 16000, 22050, 44100
		float sampleRate = 8000.0F;
		//8, 16
		int sampleSizeInBits = 16;
		//1, 2
		int channels = 1;
		boolean signed = true;
		boolean bigEndian = false;
		return new AudioFormat( sampleRate, sampleSizeInBits,channels, signed, bigEndian);
	}
	
}
Code:
import java.io.ByteArrayOutputStream;

/**
 * Thread to capture the audio files
 * Stop if stopButton applied
 * @author antoras
 *
 */
public class CaptureThread extends Thread {
	
	private byte tempBuffer[] = new byte[10000];
	
	private Sound sound = new Sound();
	
	/**
	 * The data can not directly written to the byteArrayOutputStream.
	 * Therefore they must buffered.
	 */
	public void run() {
		sound.byteArrayOutputStream = new ByteArrayOutputStream();
		sound.stopCapture = false;
		
		try {
			//Loop until the stopButton is applied
			while (!sound.stopCapture) {	
				int cnt = sound.targetDataLine.read(tempBuffer, 0, tempBuffer.length);
				if (cnt > 0) {
					sound.byteArrayOutputStream.write(tempBuffer, 0, cnt);
				}
			}
			sound.byteArrayOutputStream.close();
		} catch (Exception e) {
			System.out.println(e);
			System.exit(0);
		}
	}

}
 

Antoras

Top Contributor
Ah, eine einfache Lösung zu einem großen Problem. Jetzt hab ich endlich verstanden wofür das this richtig gebraucht wird. Glaub ich jedenfalls. :wink:

Danke dir! :D

Wobei ich gerade nochmal ein Problem habe:

Ich erstelle Buttons, die entweder aktiviert oder dektiviert sollen wenn einer dieser Buttons betätigt wird. Beim ersten Versuch hat das auch geklappt. Nur beim zweiten, bei dem ich die Buttons mit Hilfe einer Methode erstelle klappt es nicht mehr (der auskommentierte Bereich ist der alte Code)
Code:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

import javax.swing.JFrame;


/**
 * This is the main class and the GUI
 * @author antoras
 * @version 0.1,  27.01.2009
 * @since 1.6
 */
public class SoundGUI extends JFrame {

//	private JButton btnStop;
//	private JButton btnPlay;
//	private JButton btnCapture;
	
	private Sound sound = new Sound();
	

	/**
	 * Create the frame
	 */
	public SoundGUI(final int w, final int h) {
		super("Audio Suite");
		setPreferredSize(new Dimension(w, h));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocation(500, 500);

		try {
			initGUI();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		pack();
		setVisible(true);
	}
	
	/**
	 * Launch the application
	 * @param args
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					new SoundGUI(230, 40);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	/**
	 * Create the GUI
	 * @throws Exception
	 */
	private void initGUI() throws Exception {
		getContentPane().setLayout(new FlowLayout());
		
		getThis_btnCapture("capture");
		getThis_btnPlay("play");
		getThis_btnStop("Stop");

//		btnCapture = new JButton();
//		btnCapture.addActionListener(new ActionListener() {
//			public void actionPerformed(final ActionEvent e) {
//				btnCapture.setEnabled(false);
//				btnPlay.setEnabled(false);
//				btnStop.setEnabled(true);
//				sound.captureAudio();
//			}
//		});
//		btnCapture.setText("capture");
//		btnCapture.setEnabled(true);
//		getContentPane().add(btnCapture);
//
//		btnPlay = new JButton();
//		btnPlay.addActionListener(new ActionListener() {
//			public void actionPerformed(final ActionEvent e) {
//				sound.playAudio();
//			}
//		});
//		btnPlay.setText("play");
//		btnPlay.setEnabled(false);
//		getContentPane().add(btnPlay);		
//
//		btnStop = new JButton();
//		btnStop.addActionListener(new ActionListener() {
//			public void actionPerformed(final ActionEvent e) {
//				btnCapture.setEnabled(true);
//				btnPlay.setEnabled(true);
//				btnStop.setEnabled(false);
//				sound.stopCapture = true;
//			}
//		});
//		btnStop.setText("stop");
//		btnStop.setEnabled(false);
//		getContentPane().add(btnStop);
	}
	
	private JButton getThis_btnPlay(String name) {
		JButton b = new JButton(name);
		b.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				sound.playAudio();
			}
		});
		b.setEnabled(false);
		getContentPane().add(b);
		return b;
	}
	
	private JButton getThis_btnCapture(String name) {
		JButton b = new JButton(name);
		b.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				System.out.println("cap");
				getThis_btnPlay("play").setEnabled(false);
				getThis_btnCapture("capture").setEnabled(false);
				getThis_btnStop("stop").setEnabled(true);
				sound.captureAudio();
			}
		});
		b.setEnabled(true);
		getContentPane().add(b);
		return b;
	}
	
	private JButton getThis_btnStop(String name) {
		JButton b = new JButton(name);
		b.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				getThis_btnPlay("").setEnabled(true);
				getThis_btnCapture("").setEnabled(true);
				getThis_btnStop("").setEnabled(false);
				sound.stopCapture = true;
			}
		});
		b.setEnabled(false);
		getContentPane().add(b);
		return b;
	}

}
Ich vermute mal, dass die Buttons, die in den Methoden stehen nicht die selben Objekte sind, die ich am Anfang erstellt habe. Aber wie umgehe ich das Problem am besten wenn ich so viel wie möglich Code, der zu einem Button gehört in die jeweilige Methode lagern will?
 
S

SlaterB

Gast
zunächst muss der String-Parameter weg,
jede Methode ist sowieso individuell für einen Button, dann kann auch dort der Name festgelegt werden

des weiteren brauchst du Klassenattribute für die Buttons, du musst sie länger speichern denn später willst du wieder auf sie zugreifen, um sie zu 'enableln'

die Methoden haben dann folgenden Grundaufbau:
Code:
public JButton getButtonX() {
  if (this.buttonX != null) {
    return this.buttonX;
  }
  JButton newButton = ..
  ..
  ..

  this.buttonX = newButton;
  return this.buttonX;
}
allerdings darfst du dich nicht verleiten lassen, irgendwo anders direkt auf das Attribut this.buttonX zuzugreifen,
immer nur getButtonX() benutzen
 

Antoras

Top Contributor
Ok, also jetzt geht wieder alles. :D Ich habe allerdings keinen neuen Button in der getButtonX-Methode erstellt - nehme an, dass du dich da vertippt hast.
Code:
private JButton btnPlay = null;
//[...]
private void initGUI() throws Exception {
	getContentPane().setLayout(new FlowLayout());	

	getButtonPlay().setEnabled(false);
}
//[...]
public JButton getButtonPlay() {
		if (this.btnPlay != null) {
			return this.btnPlay;
		}
		btnPlay = new JButton("play");
		btnPlay.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				sound.playAudio();
			}
		});		
		getContentPane().add(btnPlay);
		return this.btnPlay;
	}


Und gleich nochmal eine Ungereimtheit:

In meiner Mainklasse SoundGUI instanziiere ich die Klasse Sound:
Code:
private Sound sound = new Sound();
Im Gegensatz zu den anderen Klassen muss in im Konstruktor dieses Objekt aber nicht übergeben:
Code:
public CaptureThread(Sound sound) {
		this.sound = sound;
	}
Wieso benötige ich das Objekt einmal im Konstruktor, ein anderes Mal aber nicht? Liegt das daran, weil ich beim ersten Mal (mein erster Post) in der Klasse Sound ein neues Objekt der Klasse CaptureThread erstellt habe, in meinem GUI aber nicht nochmal ein neues Objekt erzeuge?
 
S

SlaterB

Gast
> Ich habe allerdings keinen neuen Button in der getButtonX-Methode erstellt - nehme an, dass du dich da vertippt hast.

deine Alternative ist erstmal schlecht, da du teilweise 'this.btnPlay' schreibst und dann wieder nur 'btnPlay',
entscheide dich für eine Schreibweise,

ob man nun eine andere lokale Variable zwischenzeitlich verwendet ist abgesehen von einem Micro-Synchronisations-Problem egal,
bei deinem Programm gewiss egal,

ich schätze diese Variante noch, weil man dann nicht ständig this.btnPlay schreiben muss, falls man die this.-Schreibweise berücksichtigt

--------

Sound sollte nur einmal erzeugt werden, falls andere Klassen das benötigen, dann z.B. im Konstruktor übergeben, korrekt
 

Antoras

Top Contributor
Also, ich glaub ich hab die Funktion von this noch immer nicht richtig verstanden. Das Schlüsselwort ist sozusagen ja eine Referenz zu dem jetzigen benutzten Objekt.
Aber beispielsweise innerhalb einer Methode zur Buttonerstellung, da ist das doch gar nicht nötig. Die Methode funktioniert auch ohne this - es wird ja auch nur auf den Button gezeigt.

So sieht die Methode wohl aus wenn überall ein this steht:
Code:
public JButton getButtonPlay() {
		if (this.btnPlay != null) {
			return this.btnPlay;
		}
		this.btnPlay = new JButton("play");
		this.btnPlay.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				sound.playAudio();
			}
		});
		getContentPane().add(this.btnPlay);
		return this.btnPlay;
	}
Was macht das this dann aber für ein Sinn, wenn ich sie theoretisch auch alle weg lassen könnte?

Zumahl, wenn ich einen Button in der Methode zum Button erstellen erstelle, dann funktioniert mein setEnabled() nicht mehr wenn ich einen Button betätige:
Code:
public JButton getButtonPlay() {
		if (this.btnPlay != null) {
			return this.btnPlay;
		}
		JButton b = new JButton("play");
		b.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				sound.playAudio();
			}
		});
		b.setEnabled(false);
		getContentPane().add(b);
		return b;
	}
Ist ja auch klar. Die if-Abfrage verhindert ja, dass der restliche Code aufgerufen wird, sobald der Button einmal erstellt ist. Dann macht das ja auch keinen Sinn nochmal einen Button in der Methode zu erstelen. Auch das Auslagern der if-Abfrage in eine andere Methode, die dann getButtonX() aufruft macht keinen großen Sinn - dann ist der Code, der zusammen gehört ja wieder nicht zusammen an einem Platz.
 
S

SlaterB

Gast
> wenn ich einen Button in der Methode zum Button erstellen erstelle, dann funktioniert mein setEnabled() nicht mehr wenn ich einen Button betätige:

du musst schon allen meinen Code übernehmen, da steht am Ende
> this.buttonX = newButton;
> return this.buttonX;

bzw. mit b und btnPlay:
this.btnPlay = b;
return this.btnPlay ;


ohne das wird jedesmal ein neuer Button erstellt, das wäre in der Tat schlecht

-------

> Was macht das this dann aber für ein Sinn, wenn ich sie theoretisch auch alle weg lassen könnte?

das this. vewendet man zur Kennzeichnung, um sofort zu erkennen ob es eine lokale Variable oder ein Klassenattribut ist,
 

Antoras

Top Contributor
Hab die Button-Methoden jetzt nochmal überarbeitet. Jetzt geht es. Und wieder ein bisschen schlauer. ;)

SlaterB hat gesagt.:
das this. vewendet man zur Kennzeichnung, um sofort zu erkennen ob es eine lokale Variable oder ein Klassenattribut ist,
Aha. Gut, das leuchtet ein. Dann hoffe ich mal, dass das für mich vorerst (besser: für immer) gelöst wäre.

Danke dir :D
 

Schandro

Top Contributor
2. Wichtiger Grund, warum es this gibt: ohne this könntest du sowas nicht schreiben:
Code:
class A{
	public void übergibDich(){new B(this);}
}
class B{
	public B(A myA){}
}
 

Antoras

Top Contributor
Das ist doch an sich das Gleiche wie bei meinem anfänglichen Problem: Man braucht das this für die Wertübergabe eines Objektes, das in einem Objekt erstellt wird. Oder so ähnlich.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Nullpointer beim befüllen meiner Liste im Object Java Basics - Anfänger-Themen 3
U Warum kriege ich hier eine nullpointer exception, sehe den Fehler nicht (swing) Java Basics - Anfänger-Themen 1
Dimax BufferedReader.readLine().length() wirft NullPointer Java Basics - Anfänger-Themen 6
AlexG. Nullpointer Exeption Java Basics - Anfänger-Themen 46
AlexG. Nullpointer exeption Fehler Java Basics - Anfänger-Themen 0
B EJB und Arquillian - bekomme Nullpointer Exception beim Aufruf der EJB Klasse Java Basics - Anfänger-Themen 40
D Warum die Nullpointer Exception Java Basics - Anfänger-Themen 6
F Referenz an ein Objekt in einer anderen Klasse erstellen(Nullpointer exception) Java Basics - Anfänger-Themen 6
N Nullpointer exception Java Basics - Anfänger-Themen 4
D Erste Schritte Java.lang.NullPointer.Exception Java Basics - Anfänger-Themen 8
Z Getter/Setter NullPointer Exception Java Basics - Anfänger-Themen 6
W Nullpointer Exception bei .add(...) Java Basics - Anfänger-Themen 6
J Nullpointer aber wo? Java Basics - Anfänger-Themen 12
B OOP Über einen AVL-Baum iterieren (NullPointer) Java Basics - Anfänger-Themen 5
F Operatoren Wieso fliegt hier eine NullPointer Exception :( Java Basics - Anfänger-Themen 3
F nullpointer exception - arrayerstellung Java Basics - Anfänger-Themen 4
K Nullpointer beim Erstellen eines Imageicons Java Basics - Anfänger-Themen 2
O Perfomance: Arraylist absichtlich zum Nullpointer schicken... Java Basics - Anfänger-Themen 16
S Iterator next() Nullpointer Java Basics - Anfänger-Themen 2
W Nullpointer bei Objekt Serialisierung mit ArrayList<byte[]> etc. Java Basics - Anfänger-Themen 2
R indexOf wirft NullPointer Exception Java Basics - Anfänger-Themen 2
Q CardLayout und NullPointer Java Basics - Anfänger-Themen 3
R NullPointer Exceptions Java Basics - Anfänger-Themen 3
P ArrayList Nullpointer? Java Basics - Anfänger-Themen 4
H Nullpointer Exception Java Basics - Anfänger-Themen 8
P NullPointer Exception Java Basics - Anfänger-Themen 6
C Erste Schritte GUI - ActionListener - Exception Nullpointer Java Basics - Anfänger-Themen 5
M TextField Nullpointer Exc Java Basics - Anfänger-Themen 8
C Java Nullpointer Exception in 2D-Spiel Snake Java Basics - Anfänger-Themen 8
N NullPointer Exception bei setSource (Audioplayer mit JMF) Java Basics - Anfänger-Themen 6
I Array - Nullpointer Ausnahme Java Basics - Anfänger-Themen 2
J Methoden in externer Klasse -> Nullpointer Exception Java Basics - Anfänger-Themen 9
J NullPointer bei ArrayList.add Java Basics - Anfänger-Themen 6
J Nullpointer Exception - Warum? Java Basics - Anfänger-Themen 9
C NullPointer Java Basics - Anfänger-Themen 3
D NullPointer bei ActionCommand in Array Java Basics - Anfänger-Themen 2
D Dubioser Nullpointer Java Basics - Anfänger-Themen 5
M Java3D TransformChanged nullpointer ??? Java Basics - Anfänger-Themen 2
K zufallszahlen in Array Speichern = Nullpointer exception Java Basics - Anfänger-Themen 24
X Nullpointer Fehler Java Basics - Anfänger-Themen 3
D Nullpointer Exception Java Basics - Anfänger-Themen 2
Developer_X NullPointer Exception ohne Sinn Java Basics - Anfänger-Themen 19
MEETyA NullPointer Exception - Sudoku Java Basics - Anfänger-Themen 2
R Probleme mit NullPointer beim Mp3 abspielen (JMF) Java Basics - Anfänger-Themen 21
D Nullpointer exception bei: if( (rc.getTower != null) ) {..} Java Basics - Anfänger-Themen 2
Antoras Swing repaint und Nullpointer Java Basics - Anfänger-Themen 6
G NullPointer bei if anweisung Java Basics - Anfänger-Themen 14
Antoras NullPointer und Swing-Problem Java Basics - Anfänger-Themen 2
G (csv)Datei lesen FindBug findet mgl. NullPointer - wie lösen Java Basics - Anfänger-Themen 3
A g=panel.getGraphics() im Thread => Nullpointer Java Basics - Anfänger-Themen 9
G Problem mit Nullpointer Exception Java Basics - Anfänger-Themen 2
K Nullpointer Exception? Was tun? Java Basics - Anfänger-Themen 7
T KeyListener, Nullpointer und eine unbekannte Variable Java Basics - Anfänger-Themen 6
E Fehler NullPointer beim Ausführen Java Basics - Anfänger-Themen 4
E nullpointer bei BufferedImage Java Basics - Anfänger-Themen 2
R Wieder mal ne NullPointer Exception. Java Basics - Anfänger-Themen 8
D nullpointer exception Java Basics - Anfänger-Themen 12
S Arrays und Nullpointer Java Basics - Anfänger-Themen 6
D Problem mit Vector / Nullpointer Exception Java Basics - Anfänger-Themen 3
S Nullpointer Exception bei Point2D Java Basics - Anfänger-Themen 2
8 JLayer Nullpointer Exception Java Basics - Anfänger-Themen 6
megachucky kleines problem mit einer nullpointer exception Java Basics - Anfänger-Themen 2
B NullPointer... Java Basics - Anfänger-Themen 6
J Wertübergabe Java Basics - Anfänger-Themen 12
S array wertübergabe Java Basics - Anfänger-Themen 18
K Kennt jemand ein gutes Tutorial für Wertübergabe? Java Basics - Anfänger-Themen 4
S Innere Klasse, Wertübergabe (String) Java Basics - Anfänger-Themen 7
G g.drwaq wertübergabe Java Basics - Anfänger-Themen 3
G Wertübergabe? Java Basics - Anfänger-Themen 3
D Problem bei Wertübergabe Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben