Erstmal die Codes:
Die GUI (mit einem GUIBuilder gemacht, da ich gerade keine Lust hatte, das alles selber zu machen
import java.awt.Color;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class MusikPlayer extends javax.swing.JFrame {
/**
* Creates new form MusikPlayer
*/
public MusikPlayer() {
listModel = new DefaultListModel<>();
initComponents();
initList();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane2 = new javax.swing.JScrollPane();
musikDateienListe = new javax.swing.JList();
beendenButton = new javax.swing.JButton();
listeLeerenButton = new javax.swing.JButton();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
dateiÖffnen = new javax.swing.JMenuItem();
mehrereDateien = new javax.swing.JMenuItem();
ordnerÖffnen = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JPopupMenu.Separator();
beendenMenu = new javax.swing.JMenuItem();
jMenu2 = new javax.swing.JMenu();
jMenu3 = new javax.swing.JMenu();
jMenu4 = new javax.swing.JMenu();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("MusikPlayer");
musikDateienListe.setModel(listModel);
jScrollPane2.setViewportView(musikDateienListe);
beendenButton.setText("Beenden");
beendenButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
beendenButtonActionPerformed(evt);
}
});
listeLeerenButton.setText("Liste leeren");
listeLeerenButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
listeLeerenButtonActionPerformed(evt);
}
});
jMenuBar1.setBorder(new LineBorder(Color.BLACK));
jMenu1.setText("Datei");
dateiÖffnen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
dateiÖffnen.setText(" Datei öffnen");
dateiÖffnen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
dateiÖffnenActionPerformed(evt);
}
});
jMenu1.add(dateiÖffnen);
mehrereDateien.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
mehrereDateien.setText("Mehrere Dateien öffnen");
mehrereDateien.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mehrereDateienActionPerformed(evt);
}
});
jMenu1.add(mehrereDateien);
ordnerÖffnen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.ALT_MASK));
ordnerÖffnen.setText("Ganzen Ordner öffnen");
ordnerÖffnen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ordnerÖffnenActionPerformed(evt);
}
});
jMenu1.add(ordnerÖffnen);
jMenu1.add(jSeparator1);
beendenMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
beendenMenu.setText("Beenden");
beendenMenu.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
beendenMenuActionPerformed(evt);
}
});
jMenu1.add(beendenMenu);
jMenuBar1.add(jMenu1);
jMenu2.setText("Einstellungen");
jMenuBar1.add(jMenu2);
jMenu3.setText("Ansicht");
jMenuBar1.add(jMenu3);
jMenu4.setText("Hilfe");
jMenuBar1.add(jMenu4);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 462, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(beendenButton, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(listeLeerenButton, javax.swing.GroupLayout.Alignment.TRAILING))))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {beendenButton, listeLeerenButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(27, 27, 27)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
.addGap(5, 5, 5)
.addComponent(listeLeerenButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(beendenButton)
.addContainerGap())
);
pack();
}// </editor-fold>
private void beendenButtonActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
@SuppressWarnings("ResultOfObjectAllocationIgnored")
private void ordnerÖffnenActionPerformed(java.awt.event.ActionEvent evt) {
// if (Musik.isPlaying) {
// Musik.player.close();
// Musik.isPlaying = false;
// MusikThread.audioFiles = null;
// }
new Musik(false, true);
}
@SuppressWarnings("ResultOfObjectAllocationIgnored")
private void mehrereDateienActionPerformed(java.awt.event.ActionEvent evt) {
// if (Musik.isPlaying) {
// Musik.player.close();
// Musik.isPlaying = false;
// MusikThread.audioFiles = null;
// }
new Musik(true, false);
}
private void beendenMenuActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
@SuppressWarnings("ResultOfObjectAllocationIgnored")
private void dateiÖffnenActionPerformed(java.awt.event.ActionEvent evt) {
new Musik(false, false);
}
private void listeLeerenButtonActionPerformed(java.awt.event.ActionEvent evt) {
listModel.clear();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MusikPlayer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MusikPlayer().setVisible(true);
}
});
}
static DefaultListModel<File> listModel;
// Variables declaration - do not modify
private javax.swing.JButton beendenButton;
private javax.swing.JMenuItem beendenMenu;
private javax.swing.JMenuItem dateiÖffnen;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenu jMenu3;
private javax.swing.JMenu jMenu4;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JPopupMenu.Separator jSeparator1;
private javax.swing.JButton listeLeerenButton;
private javax.swing.JMenuItem mehrereDateien;
static javax.swing.JList musikDateienListe;
private javax.swing.JMenuItem ordnerÖffnen;
// End of variables declaration
private void initList() {
musikDateienListe.addListSelectionListener(new ListSelectionListener() {
@Override
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public void valueChanged(ListSelectionEvent lse) {
// Musik.player.close();
// File[] newAudioFiles = MusikThread.audioFiles;
// MusikThread.audioFiles = null;
// try {
// Musik.player = new Player(new FileInputStream((File) musikDateienListe.getSelectedValue()));
// Musik.player.play();
// MusikThread.audioFiles = newAudioFiles;
// } catch (JavaLayerException | FileNotFoundException ex) {
// Logger.getLogger(MusikPlayer.class.getName()).log(Level.SEVERE, null, ex);
// }
new ListThread();
}
});
}
}
Der Player + das ganze Auswahl-Gedöns:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import javazoom.jl.decoder.*;
import javazoom.jl.player.Player;
public class Musik implements Runnable {
FileInputStream inputStream;
static Player player;
static boolean isPlaying = false;
static Thread t = new Thread(new Musik());
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public Musik(boolean multiSelection, boolean onlyDirectories) {
t.setName("Musik");
JFileChooser musikChooser = new JFileChooser();
File startFile = new File("E:\\Metin2\\");
musikChooser.removeChoosableFileFilter(musikChooser.getFileFilter());
FileNameExtensionFilter filter = new FileNameExtensionFilter("Unterstützte Musik-Formate", "wav", "mp3");
musikChooser.setFileFilter(filter);
musikChooser.setCurrentDirectory(startFile);
musikChooser.setMultiSelectionEnabled(multiSelection);
if (onlyDirectories) {
musikChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
int returnVal = musikChooser.showDialog(musikChooser, "MusikTrack wählen");
if (returnVal == JFileChooser.APPROVE_OPTION) {
if (!onlyDirectories) {
if (multiSelection) {
File[] audioFiles = musikChooser.getSelectedFiles();
for (File audioFile : audioFiles) {
MusikPlayer.listModel.addElement(audioFile);
}
if (MusikThread.audioFiles == null) {
new MusikThread(audioFiles);
} else {
File[] oldFiles = MusikThread.audioFiles;
File[] newFiles = audioFiles;
int newLength = oldFiles.length + newFiles.length;
File[] resultFiles;
resultFiles = Arrays.copyOf(oldFiles, newLength);
System.arraycopy(newFiles, 0, resultFiles, oldFiles.length, newFiles.length);
MusikThread.setAudioFiles(resultFiles);
}
} else {
File newAudioFile = musikChooser.getSelectedFile();
MusikPlayer.listModel.addElement(newAudioFile);
if (MusikThread.audioFiles == null) {
new MusikThread(newAudioFile);
} else {
File[] oldFiles = MusikThread.audioFiles;
File[] newFile = {newAudioFile};
int newLength = oldFiles.length + newFile.length;
File[] resultFiles;
resultFiles = Arrays.copyOf(oldFiles, newLength);
System.arraycopy(newFile, 0, resultFiles, oldFiles.length, newFile.length);
MusikThread.setAudioFiles(resultFiles);
}
}
} else {
File[] audioFiles = musikChooser.getSelectedFile().listFiles();
for (File audioFile : audioFiles) {
MusikPlayer.listModel.addElement(audioFile);
}
if (MusikThread.audioFiles == null) {
new MusikThread(audioFiles);
} else {
File[] oldFiles = MusikThread.audioFiles;
File[] newFiles = audioFiles;
int newLength = oldFiles.length + newFiles.length;
File[] resultFiles = Arrays.copyOf(oldFiles, newLength);
System.arraycopy(newFiles, 0, resultFiles, oldFiles.length, newFiles.length);
MusikThread.setAudioFiles(resultFiles);
}
}
}
}
Musik() {
}
@Override
public void run() {
try {
if (!isPlaying) {
if (!ListThread.isListThreading) {
System.out.println("Starte Lied");
isPlaying = true;
player.play();
isPlaying = false;
System.out.println("Lied zuende");
}
}
} catch (JavaLayerException ex) {
FileHandler fh = null;
try {
fh = new FileHandler("syserr.xml.log");
} catch (IOException ex1) {
System.err.println("Filehandler bei Musik kaputt");
}
Logger log = Logger.getLogger(Musik.class.getName());
log.addHandler(fh);
log.log(Level.SEVERE, null, ex);
}
}
}```
```package MusikPlayer;
import static MusikPlayer.Musik.isPlaying;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
public class MusikThread implements Runnable {
FileInputStream inputStream;
static File[] audioFiles;
Thread t = new Thread(this);
public MusikThread(File... audioFiles) {
MusikThread.audioFiles = audioFiles;
t.start();
}
public static void setAudioFiles(File[] audioFiles) {
MusikThread.audioFiles = audioFiles;
}
@Override
public void run() {
for (File audioFile : audioFiles) {
try {
if (!isPlaying) {
t = new Thread(this);
t.setName("MusikThread");
Musik.t = new Thread(new Musik());
inputStream = new FileInputStream(audioFile);
System.out.println("InputStream gesetzt");
Musik.player = new Player(inputStream);
Musik.t.start();
Musik.t.join();
ListThread.t.join();
if (audioFiles == null) {
System.out.println("For-Schleife abgebrochen");
break;
}
}
} catch (FileNotFoundException | JavaLayerException | InterruptedException ex) {
FileHandler fh = null;
try {
fh = new FileHandler("syserr.xml.log");
} catch (IOException ex1) {
System.err.println("Filehandler bei Musik kaputt");
}
Logger log = Logger.getLogger(MusikThread.class.getName());
log.addHandler(fh);
log.log(Level.SEVERE, null, ex);
}
System.out.println("For-Schleife beendet");
}
}
}
Die Liste mit den ganzen Dateien als Thread:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
public class ListThread implements Runnable {
static Thread t;
static boolean isListThreading = false;
public ListThread() {
t = new Thread(new ListThread(true));
t.setName("ListThread");
t.start();
}
public ListThread(boolean useless) {
}
@Override
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public void run() {
System.out.println("Musikplayer im ListThread geschlossen");
Musik.player.close();
File[] newAudioFiles = MusikThread.audioFiles;
MusikThread.audioFiles = null;
isListThreading = true;
try {
System.out.println("Im Try bei ListThread");
Musik.player = new Player(new FileInputStream((File) MusikPlayer.musikDateienListe.getSelectedValue()));
Musik.player.play();
MusikThread.audioFiles = newAudioFiles;
Musik.player.close();
new MusikThread(newAudioFiles);
System.out.println("ListThread fertig");
} catch (JavaLayerException | FileNotFoundException ex) {
Logger.getLogger(ListThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
So und nun zur Problembeschreibung:
Ich starte das Programm, alles Wunderbar
Ich wähle ein paar Lieder/nen Ordner/eine Datei aus, alles gut und er spielt das erste ab. Ausgabe hier:
InputStream gesetzt
Starte Lied
Dann wähle ich in der Liste ein anderes aus, er unterbricht das letzte und spielt das ausgewählte ab. Auch alles super. Ausgabe hier:
InputStream gesetzt
Starte Lied
Musikplayer im ListThread geschlossen
Musikplayer im ListThread geschlossen
Im Try bei ListThread
Im Try bei ListThread
Lied zuende
(warum ist das hier eig jeweils 2x drin?)
Und jetzt kommt das Problem:
Wenn ich wieder ein anderes Lied auswähle, spielt er das neue UND das aktuelle gleichzeitig ab. Ausgabe hier:
InputStream gesetzt
Starte Lied
Musikplayer im ListThread geschlossen
Musikplayer im ListThread geschlossen
Im Try bei ListThread
Im Try bei ListThread
Lied zuende
Musikplayer im ListThread geschlossen
Im Try bei ListThread
Exception in thread „Thread-11“ java.lang.NullPointerException
ListThread fertig
at MusikPlayer.MusikThread.run(MusikThread.java:31)
For-Schleife abgebrochen
at java.lang.Thread.run(Thread.java:724)
Musikplayer im ListThread geschlossen
Im Try bei ListThread
ListThread fertig
Exception in thread „Thread-13“ java.lang.NullPointerException
at MusikPlayer.MusikThread.run(MusikThread.java:31)
at java.lang.Thread.run(Thread.java:724)