Added library folder settings and connected library update functionality.
This commit is contained in:
parent
48a368e410
commit
9ea708d20a
2
.gitignore
vendored
2
.gitignore
vendored
@ -68,3 +68,5 @@ buildNumber.properties
|
|||||||
.mvn/timing.properties
|
.mvn/timing.properties
|
||||||
|
|
||||||
# Created by .ignore support plugin (hsz.mobi)
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
|
||||||
|
settings.cfg
|
71
src/main/java/musicplayer/LibraryConfigGUI.java
Normal file
71
src/main/java/musicplayer/LibraryConfigGUI.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package musicplayer;
|
||||||
|
|
||||||
|
import musicplayer.swingmodels.LibraryListModel;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LibraryConfigGUI {
|
||||||
|
private JList listLibraryFolders;
|
||||||
|
private LibraryListModel listModel = new LibraryListModel();
|
||||||
|
private JPanel mainPanel;
|
||||||
|
|
||||||
|
public LibraryConfigGUI(){
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
frame.setContentPane(createUI());
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
frame.pack();
|
||||||
|
frame.setVisible(true);
|
||||||
|
updateLibraryListContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel createUI() {
|
||||||
|
mainPanel = new JPanel();
|
||||||
|
mainPanel.setLayout(new BorderLayout(0, 0));
|
||||||
|
listLibraryFolders = new JList();
|
||||||
|
listLibraryFolders.setModel(listModel);
|
||||||
|
mainPanel.add(listLibraryFolders, BorderLayout.CENTER);
|
||||||
|
final JPanel panel2 = new JPanel();
|
||||||
|
panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
|
||||||
|
mainPanel.add(panel2, BorderLayout.EAST);
|
||||||
|
JButton addNewButton = new JButton();
|
||||||
|
addNewButton.setText("Add New");
|
||||||
|
addNewButton.addActionListener(e -> addNew());
|
||||||
|
panel2.add(addNewButton);
|
||||||
|
JButton removeButton = new JButton();
|
||||||
|
removeButton.setText("Remove");
|
||||||
|
removeButton.addActionListener(e -> removeSelected());
|
||||||
|
panel2.add(removeButton);
|
||||||
|
return mainPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLibraryListContents(){
|
||||||
|
listModel.setFolderList(LibraryUtils.getLibraryDirectories());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveLibraryList(){
|
||||||
|
List<File> folders = listModel.currentFolderList();
|
||||||
|
LibraryUtils.saveLibrarySettings(folders);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNew(){
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
fileChooser.setAcceptAllFileFilterUsed(false);
|
||||||
|
if (fileChooser.showOpenDialog(mainPanel) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File targetFile = fileChooser.getSelectedFile();
|
||||||
|
if(!listModel.contains(targetFile)) {
|
||||||
|
listModel.addFolder(targetFile);
|
||||||
|
saveLibraryList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSelected(){
|
||||||
|
List<File> files = listLibraryFolders.getSelectedValuesList();
|
||||||
|
files.forEach(listModel::removeFile);
|
||||||
|
saveLibraryList();
|
||||||
|
}
|
||||||
|
}
|
@ -10,15 +10,52 @@ import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
|||||||
import org.jaudiotagger.tag.Tag;
|
import org.jaudiotagger.tag.Tag;
|
||||||
import org.jaudiotagger.tag.TagException;
|
import org.jaudiotagger.tag.TagException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public final class LibraryUtils {
|
public final class LibraryUtils {
|
||||||
|
|
||||||
static final String musicFileExtensionRegex = ".*\\.(mp3|mp4|flac)";
|
static final String musicFileExtensionRegex = ".*\\.(mp3|mp4|flac|ogg)";
|
||||||
|
static final Properties librarySettings = new Properties();
|
||||||
|
static final String settingsFilename = "settings.cfg";
|
||||||
|
static final File propertiesFile = new File(settingsFilename);
|
||||||
|
private static List<File> libraryDirectories;
|
||||||
|
static final String foldersKey = "libraryFolders";
|
||||||
|
|
||||||
|
public static List<File> getLibraryDirectories(){
|
||||||
|
loadLibrarySettings(); // Make sure libraryDirectories matches the stored version.
|
||||||
|
return libraryDirectories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadLibrarySettings(){
|
||||||
|
try(FileInputStream inputStream = new FileInputStream(propertiesFile)){
|
||||||
|
librarySettings.load(inputStream);
|
||||||
|
if(librarySettings.containsKey(foldersKey)){
|
||||||
|
libraryDirectories = Arrays.asList(librarySettings.getProperty(foldersKey).split(","))
|
||||||
|
.stream().map(File::new).filter(File::exists).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
propertiesFile.getParentFile().mkdirs();
|
||||||
|
try {
|
||||||
|
propertiesFile.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveLibrarySettings(List<File> folderList){
|
||||||
|
librarySettings.setProperty(foldersKey, folderList.stream().map(File::toString).collect(Collectors.joining(",")));
|
||||||
|
try(FileWriter fileWriter = new FileWriter(settingsFilename)){
|
||||||
|
librarySettings.store(fileWriter, "");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void processSongsWithCallback(List<Path> rootDirectory, LibraryCallbackInterface callbackInterface){
|
public static void processSongsWithCallback(List<Path> rootDirectory, LibraryCallbackInterface callbackInterface){
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
|
@ -6,6 +6,7 @@ import musicplayer.db.DatabaseManager;
|
|||||||
import musicplayer.db.Gateway;
|
import musicplayer.db.Gateway;
|
||||||
import musicplayer.model.Album;
|
import musicplayer.model.Album;
|
||||||
import musicplayer.model.Song;
|
import musicplayer.model.Song;
|
||||||
|
import musicplayer.swingmodels.PlaylistTableModel;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
@ -15,8 +16,11 @@ import java.awt.*;
|
|||||||
import java.awt.event.ItemEvent;
|
import java.awt.event.ItemEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterface {
|
public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterface {
|
||||||
public JPanel mainPanel;
|
public JPanel mainPanel;
|
||||||
@ -195,10 +199,20 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
|
|||||||
populateThread.start();
|
populateThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLibrary(){
|
||||||
|
DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode());
|
||||||
|
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) model.getRoot();
|
||||||
|
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("Updating Library...");
|
||||||
|
addNodeToTreeModel(model, parentNode, newNode);
|
||||||
|
libraryView.setModel(model);
|
||||||
|
List<Path> dirs = LibraryUtils.getLibraryDirectories().stream().map(File::toPath).collect(Collectors.toList());
|
||||||
|
LibraryUtils.processSongsWithCallback(dirs, this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void libraryUpdated(boolean successful) {
|
public void libraryUpdated(boolean successful) {
|
||||||
if (successful)
|
if (successful)
|
||||||
libraryDisplayVariants.get(libraryDisplayType.getSelectedItem().toString()).run();
|
refreshLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Runnable> createDisplayVariantMap() {
|
private Map<String, Runnable> createDisplayVariantMap() {
|
||||||
@ -342,7 +356,11 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
|
|||||||
|
|
||||||
menuItem = new JMenuItem("Update Library");
|
menuItem = new JMenuItem("Update Library");
|
||||||
menuItem.setToolTipText("Reindex and refresh library.");
|
menuItem.setToolTipText("Reindex and refresh library.");
|
||||||
|
menuItem.addActionListener(e -> updateLibrary());
|
||||||
|
tools.add(menuItem);
|
||||||
|
|
||||||
|
menuItem = new JMenuItem("Library Settings");
|
||||||
|
menuItem.addActionListener(e -> new LibraryConfigGUI());
|
||||||
tools.add(menuItem);
|
tools.add(menuItem);
|
||||||
|
|
||||||
// Add everything to the menu bar itself
|
// Add everything to the menu bar itself
|
||||||
|
49
src/main/java/musicplayer/swingmodels/LibraryListModel.java
Normal file
49
src/main/java/musicplayer/swingmodels/LibraryListModel.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package musicplayer.swingmodels;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LibraryListModel extends AbstractListModel {
|
||||||
|
|
||||||
|
private List<File> libraryFolders = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return libraryFolders.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getElementAt(int index) {
|
||||||
|
return libraryFolders.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFolder(File folder){
|
||||||
|
if(folder.exists() && folder.isDirectory()) {
|
||||||
|
libraryFolders.add(folder);
|
||||||
|
fireContentsChanged(this, 0, libraryFolders.size() == 0 ? 0 : libraryFolders.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<File> currentFolderList(){
|
||||||
|
return new ArrayList<>(libraryFolders); // Copy? Don't want modification via here.
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(File file){
|
||||||
|
return libraryFolders.contains(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFolderList(List<File> folderList){
|
||||||
|
if(folderList != null && folderList.size() > 0)
|
||||||
|
libraryFolders = new ArrayList<>(folderList);
|
||||||
|
else
|
||||||
|
libraryFolders = new ArrayList<>();
|
||||||
|
fireContentsChanged(this, 0, libraryFolders.size() == 0 ? 0 : libraryFolders.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeFile(File file){
|
||||||
|
libraryFolders.remove(file);
|
||||||
|
fireContentsChanged(this, 0, libraryFolders.size() == 0 ? 0 : libraryFolders.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package musicplayer;
|
package musicplayer.swingmodels;
|
||||||
|
|
||||||
import musicplayer.model.Song;
|
import musicplayer.model.Song;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user