Hello everyone,
I am working on a little project done with swing. Since I need an mp3 player inside my swing application, I found a really good solution with JavaFX 2. I have never worked with JavaFX before, therefor it seems to me a little bit strange on some parts.
Anyway.
I created a button on my application and as soon as somebody presses that button, the application should scan recursivly a unique directory for mp3 files and store the information of artist, title and track length into a database.
The mp3 player I created is based on the example from this page:
http://www.java2s.com/Code/Java/JavaFX/Mp3playerwithmetadataviewandcontrolpanel.htm
I understand the source code for most parts, but some behaivors are not really clear to me. My thoughts about getting the complete length of the mp3 file was
media.getDuration
or
mediaplayer.getTotalDuration
but both results are NaN if I call .toMillis();
Instead I need to create a listener (why?)
private class TotalDurationListener implements InvalidationListener {
@Override
public void invalidated(Observable observable) {
final MediaPlayer mediaPlayer = songModel.getMediaPlayer();
final Duration totalDuration = mediaPlayer.getTotalDuration();
totalDurationLabel.setText(formatDuration(totalDuration));
}
}
and register this listener on the mediaplayer
mp.totalDurationProperty().addListener(new TotalDurationListener());
I can image that the mediaplayer can "host" several media objects somewho and the listener is called as soon as a new media will be added to the mediaplayer in order
the calculate the overall duration.
When is this listener exactly called and is there no other ways to get the total length of the mp3 file?
Here is a minimal example which should work without any external libs
package de.hauke.schwimmbad.application.playground;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class Testing10 extends JFrame {
private MediaPlayer mediaPlayer;
private final ReadOnlyObjectWrapper<MediaPlayer> mediaPlayerWrapper = new ReadOnlyObjectWrapper<MediaPlayer>(
this, "mediaPlayer");
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Testing10();
} catch (Exception ex) {
System.out.println(ex);
}
}
public Testing10() {
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setSize(500, 500);
setTitle("Testing");
setLocationRelativeTo(null);
setResizable(false);
JButton button = new JButton("Scan");
button.setBounds(10, 10, 150, 30);
add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
scan();
}
});
final JFXPanel fxPanel = new JFXPanel();
fxPanel.setBounds(30, 80, 300, 300);
add(fxPanel);
Platform.runLater(new Runnable() {
public void run() {
initFX(fxPanel);
}
});
setVisible(true);
}
private void scan() {
File directory = new File("C:\\dev\\mp3");
List<File> mp3Files = new ArrayList<File>();
for (File file : directory.listFiles()) {
if(file.getName().endsWith("mp3")) {
mp3Files.add(file);
}
}
for (File file : mp3Files) {
System.out.println(file.getAbsoluteFile());
getLength(file);
}
}
private Duration getLength(File file) {
if(mediaPlayer != null) {
mediaPlayer.stop();
}
final Media media = new Media(file.toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaPlayerWrapper.setValue(mediaPlayer);
if(media.durationProperty()==null) System.out.println("durationProperty ist null");
if(media.durationProperty().get()==null) System.out.println(".get() ist null");
System.out.println("---> " + media.durationProperty().get().toMillis());
return media.getDuration();
}
private void initFX(JFXPanel fxPanel) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, Color.ALICEBLUE);
fxPanel.setScene(scene);
}
}
The other question is why do I need a listener for the meta data to be changed in order to get the meta data?
media.getMetadata().addListener(new MapChangeListener<String, Object>()
Why can't I call something like
media.getMetadata() --> returns a filled map?
The metadata problem is not included inside the example from above.
Sorry for my english but I hope everybody can understand the issue.
Many greetings,
Hauke