JavaFX - ArrayLists печатаются как пустые после вставки тегов мультимедиа, извлеченных из аудиофайлов - PullRequest
0 голосов
/ 20 ноября 2018

Я новичок в программировании на Java и пытаюсь разработать класс, который может извлекать теги мультимедиа (такие как название, исполнитель, ...) из импортированных файлов MP3, таким образом я могу сохранить их в личная база данных MySQL.

У меня есть проблема, которую я пытался решить уже пару дней, но я не мог найти решение онлайн.

Это мой класс:

public class FileImportClass extends Application {

    private static final Object obj = new Object();
    private static List<File> songList;
    private static ArrayList<String> title;
    private static ArrayList<String> artist;
    private static ArrayList<Integer> year;
    private static ArrayList<String> genre;
    private static ArrayList<String> duration;
    private static ArrayList<String> album;
    private static ArrayList<String> extension;
    private static ArrayList<String> size;
    private static ObservableMap<String, Object> songTags;

    public static void FileImport(Node node){
        title = new ArrayList<>();
        artist = new ArrayList<>();
        year = new ArrayList<>();
        genre = new ArrayList<>();
        duration = new ArrayList<>();
        album = new ArrayList<>();
        extension = new ArrayList<>();
        size = new ArrayList<>();

        FileChooser fileImport = new FileChooser();
        fileImport.setTitle("Importazione di File Audio");
        fileImport.getExtensionFilters().addAll(new ExtensionFilter("MP3 Files: ", "*.mp3"));
        Stage currentStage = (Stage) node.getScene().getWindow();
        songList = fileImport.showOpenMultipleDialog(currentStage);
        if (songList.size() > 50) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Errore!");
            alert.setHeaderText("Errore nell'inserimento dei file audio!");
            alert.setContentText("È stato superato il massimo di 50 file audio importabili alla volta.");

            alert.showAndWait(); 
            return;
        }
        else{
            for(int i = 0; i < songList.size(); i++) {
                File file = songList.get(i);
                Media mediaFile = new Media(file.toURI().toString());
                double FILE_SIZE_D = file.length();
                int FILE_SIZE_I = (int) FILE_SIZE_D;
                int FILE_SIZE = FILE_SIZE_I / 1024;
                size.add(String.valueOf(FILE_SIZE) + " kB");

                final MediaPlayer mediaPlayer = new MediaPlayer(mediaFile);
                mediaPlayer.setOnReady(new Runnable(){
                    @Override
                    public void run() {
                        songTags = mediaPlayer.getMedia().getMetadata();
                        title.add(songTags.get("title").toString());
                        artist.add(songTags.get("artist").toString());

                        double DURATA_MINUTI_D = mediaFile.getDuration().toSeconds() / 60;
                        double DURATA_MINUTI_I = (int) DURATA_MINUTI_D;
                        double DURATA_SECONDI_D = (DURATA_MINUTI_D - DURATA_MINUTI_I) * 60;
                        double DURATA_SECONDI_I = (int) DURATA_SECONDI_D;

                        duration.add(String.valueOf(DURATA_MINUTI_I) + " min " + DURATA_SECONDI_I + " s");
                        if (songTags.get("genre") != null) {
                            genre.add(songTags.get("genre").toString());
                        }
                        else {
                            genre.add("Genere sconosciuto");
                        }

                        if (songTags.get("album") != null) {
                            album.add(songTags.get("album").toString());
                        }
                        else {
                            album.add("Album sconosciuto");
                        }
                        year.add((Integer) songTags.get("year"));
                        synchronized(obj){
                            obj.notify();
                        }
                    }
                });
            }
        }
        System.out.println(title);
        System.out.println(artist);
        System.out.println(genre);
        System.out.println(size);
        System.out.println(duration);
        System.out.println(album);
        System.out.println(year);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

Проблема в том, что, когда я пытаюсь распечатать списки массивов, которые содержат теги, они становятся пустыми ("[]"). Но если я попытаюсь напечатать их из функции mediaPlayer.setOnReady (), то все будет работать нормально.

Есть ли кто-нибудь, кто мог бы помочь мне понять это?

Спасибо всем заранее!

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Как говорит Гнас, здесь есть проблема синхронности. Вам придется сделать что-то вроде этого:

В вашем цикле:

for(int i = 0; i < songList.size(); i++) {
    final int finalI = i;
    ...

В конце метода run ():

if (finalI == songList.size() - 1) {
    System.out.println(title);
    System.out.println(artist);
    System.out.println(genre);
    System.out.println(size);
}
0 голосов
/ 20 ноября 2018

Вы добавляете теги в MediaPlayer.setOnReady, который вызывается, когда состояние объекта MediaPlayer изменяется на READY.Это происходит не сразу после вызова метода, а через некоторое неизвестное время.Это означает, что ваши операторы печати выполняются до событий изменения статуса, поэтому к тому времени списки все еще пусты.

...