Library now shows the current file being indexed when the library is updating. Disabled view mode switching while updating the library.

This commit is contained in:
neviyn 2016-02-26 15:16:54 +00:00
parent 45efd42793
commit ecc789a556
8 changed files with 65 additions and 50 deletions

View File

@ -21,7 +21,7 @@ import java.util.stream.Collectors;
public final class LibraryUtils {
static final String musicFileExtensionRegex = ".*\\.(mp3|mp4|flac|ogg)";
static final String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
static final Properties librarySettings = new Properties();
static final String settingsFilename = "settings.cfg";
static final File propertiesFile = new File(settingsFilename);
@ -59,44 +59,23 @@ public final class LibraryUtils {
public static void processSongsWithCallback(List<Path> rootDirectory, LibraryCallbackInterface callbackInterface){
Thread thread = new Thread(() -> {
rootDirectory.forEach(dir -> {
try {
processSongs(rootDirectory);
callbackInterface.libraryUpdated(true);
Files.walk(dir)
.filter(f -> f.toString().matches(musicFileExtensionRegex)).map(LibraryUtils::autoParse)
.forEach(x -> x.ifPresent(i -> {
Gateway.addSong(i);
callbackInterface.currentlyUpdating(i.toString());
}));
} catch (IOException e) {
callbackInterface.libraryUpdated(false);
}
});
thread.start();
}
public static void processSongsWithCallback(Path rootDirectory, LibraryCallbackInterface callbackInterface){
Thread thread = new Thread(() -> {
try {
processSongs(rootDirectory);
callbackInterface.libraryUpdated(true);
} catch (IOException e) {
callbackInterface.libraryUpdated(false);
}
});
thread.start();
}
public static void processSongs(List<Path> rootDirectories) throws IOException {
for(Path rootDirectory: rootDirectories)
processSongs(rootDirectory);
}
/**
* Walk through all files and directories recursively and index any music files with a correct extension
*
* @param rootDirectory Directory from which to start searching
*/
public static void processSongs(Path rootDirectory) throws IOException {
Files.walk(rootDirectory)
.filter(f -> f.toString().matches(musicFileExtensionRegex))
.map(LibraryUtils::autoParse).forEach(x -> x.ifPresent(Gateway::addSong));
}
/**
* Extract music metadata from the target file.
*

View File

@ -82,6 +82,7 @@ public class Player {
playBin.stop();
internalThread.stop();
thread = null;
callbackInterface.playerStopped();
}
}

View File

@ -30,6 +30,8 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
private JComboBox libraryDisplayType = new JComboBox();
private Player player = new Player(this);
private PlaylistTableModel playlistTableModel = new PlaylistTableModel(new ArrayList<>());
private static DefaultMutableTreeNode updatingNode = new DefaultMutableTreeNode();
private boolean libraryUpdating = false;
private Map<String, Runnable> libraryDisplayVariants = createDisplayVariantMap();
@ -91,7 +93,8 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
sortedData.forEach((k, v) -> {
DefaultMutableTreeNode albumNode = new DefaultMutableTreeNode(k);
addNodeToTreeModel(model, parentNode, albumNode);
new TreeSet<>(v).forEach(x -> addNodeToTreeModel(model, albumNode, new DefaultMutableTreeNode(x)));
Collections.sort(v);
v.forEach(x -> addNodeToTreeModel(model, albumNode, new DefaultMutableTreeNode(x)));
});
libraryView.setModel(model);
}
@ -152,6 +155,7 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
public void setSongHighlighting(Song playingSong) {
int index = playlistTableModel.getSongIndex(playingSong);
playList.setRowSelectionInterval(index, index);
playlistTableModel.setPlayingRow(index);
}
/**
@ -176,6 +180,8 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
playlistTableModel.removeSong(invalidSong);
}
public void playerStopped(){ playlistTableModel.setPlayingRow(-1); }
/**
* Refresh the library with songs in the currently selected display format.
*/
@ -200,10 +206,12 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
}
private void updateLibrary(){
libraryUpdating = true;
DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode());
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) model.getRoot();
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("Updating Library...");
addNodeToTreeModel(model, parentNode, newNode);
addNodeToTreeModel(model, parentNode, updatingNode);
libraryView.setModel(model);
List<Path> dirs = LibraryUtils.getLibraryDirectories().stream().map(File::toPath).collect(Collectors.toList());
LibraryUtils.processSongsWithCallback(dirs, this);
@ -213,6 +221,13 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
public void libraryUpdated(boolean successful) {
if (successful)
refreshLibrary();
libraryUpdating = false;
}
@Override
public void currentlyUpdating(String name) {
updatingNode.setUserObject(name);
((DefaultTreeModel)libraryView.getModel()).nodeChanged(updatingNode);
}
private Map<String, Runnable> createDisplayVariantMap() {
@ -247,7 +262,7 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
libraryAndComboboxPane.setLayout(new BorderLayout(0, 0));
libraryAndPlaylistPane.setLeftComponent(libraryAndComboboxPane);
libraryDisplayType.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED)
if (!libraryUpdating && e.getStateChange() == ItemEvent.SELECTED)
libraryDisplayVariants.get(libraryDisplayType.getSelectedItem().toString()).run();
});
libraryAndComboboxPane.add(libraryDisplayType, BorderLayout.NORTH);
@ -278,6 +293,9 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
JScrollPane playlistScroll = new JScrollPane();
playList.setRowSelectionAllowed(true);
playList.setModel(playlistTableModel);
playList.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
playList.getColumnModel().getColumn(0).setPreferredWidth(10);
playList.getColumnModel().getColumn(0).setMaxWidth(10);
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem menuItem = new JMenuItem("Remove");
menuItem.addActionListener((e) -> playlistTableModel.removeSong(playList.getSelectedRows()));

View File

@ -3,4 +3,6 @@ package musicplayer.callbacks;
public interface LibraryCallbackInterface {
void libraryUpdated(boolean successful);
void currentlyUpdating(String name);
}

View File

@ -14,4 +14,6 @@ public interface PlayerCallbackInterface {
void removeInvalidSong(Song invalidSong);
void playerStopped();
}

View File

@ -19,7 +19,7 @@ public class Album implements Comparable<Album> {
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "album")
@OrderBy("trackNumber ASC")
@OrderBy("discNumber ASC, trackNumber ASC")
private Set<Song> songs;
@Lob
@Column(name = "art", nullable = true, length = 10000)

View File

@ -84,4 +84,9 @@ public class ExtractedMetadata {
g.dispose();
return newImage;
}
@Override
public String toString() {
return title + " - " + artist;
}
}

View File

@ -3,15 +3,14 @@ package musicplayer.swingmodels;
import musicplayer.model.Song;
import javax.swing.table.AbstractTableModel;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PlaylistTableModel extends AbstractTableModel {
private List<Song> songList;
private int playingRow = -1;
public PlaylistTableModel(List<Song> songList){
this.songList = songList;
@ -24,7 +23,7 @@ public class PlaylistTableModel extends AbstractTableModel {
@Override
public int getColumnCount() {
return 4;
return 6;
}
@Override
@ -32,10 +31,12 @@ public class PlaylistTableModel extends AbstractTableModel {
Object o = "?";
Song song = songList.get(rowIndex);
switch (columnIndex){
case 0: o = song.getTrackNumber(); break;
case 1: o = song.getTitle(); break;
case 2: o = song.getArtist(); break;
case 3: o = song.getAlbum(); break;
case 0: o = (playingRow == rowIndex) ? "" : " "; break;
case 1: o = song.getTrackNumber(); break;
case 2: o = song.getTitle(); break;
case 3: o = song.getArtist(); break;
case 4: o = song.getAlbum(); break;
case 5: o = song.getDiscNumber(); break;
}
return o;
}
@ -49,10 +50,12 @@ public class PlaylistTableModel extends AbstractTableModel {
public String getColumnName(int column) {
String name = "";
switch (column){
case 0: name = "Track"; break;
case 1: name = "Title"; break;
case 2: name = "Artist"; break;
case 3: name = "Album"; break;
case 0 : name = " "; break;
case 1: name = "Track"; break;
case 2: name = "Title"; break;
case 3: name = "Artist"; break;
case 4: name = "Album"; break;
case 5: name = "DiscNo"; break;
}
return name;
}
@ -108,4 +111,9 @@ public class PlaylistTableModel extends AbstractTableModel {
public Optional<Song> getSong(int index){
return songList.size() > 0 && index >= 0 && index < songList.size() ? Optional.of(songList.get(index)) : Optional.empty();
}
public void setPlayingRow(int index){
playingRow = index;
fireTableDataChanged();
}
}