Adds a toolbar and moves most functionality to actions.
This commit is contained in:
@@ -45,37 +45,15 @@ public class Collections extends JPanel
|
|||||||
this.setFocusable(true);
|
this.setFocusable(true);
|
||||||
this.setFocusCycleRoot(true);
|
this.setFocusCycleRoot(true);
|
||||||
|
|
||||||
this.add(defaultLabel = label = this.createButton(langs.getString("collections.all")));
|
this.add(defaultLabel = label = this.createButton(Interface.getInstance().actions.get("view.all")));
|
||||||
label.setMnemonic('A');
|
this.add(label = this.createButton(Interface.getInstance().actions.get("view.artists")));
|
||||||
label.addActionListener(mouseEvent -> this
|
this.add(label = this.createButton(Interface.getInstance().actions.get("view.albums")));
|
||||||
.triggerSongDisplayListeners(new ArrayList<>(SongProvider.INSTANCE.getSongs())));
|
this.add(label = this.createButton(Interface.getInstance().actions.get("view.genres")));
|
||||||
this.add(label = this.createButton(langs.getString("collections.artists")));
|
this.add(label = this.createButton(Interface.getInstance().actions.get("view.years")));
|
||||||
label.setMnemonic('T');
|
|
||||||
label.addActionListener(mouseEvent -> this
|
|
||||||
.triggerCollectionDisplayListeners(CollectionType.albumArtist, SongProvider.INSTANCE
|
|
||||||
.getAlbumArtists()));
|
|
||||||
this.add(label = this.createButton(langs.getString("collections.albums")));
|
|
||||||
label.setMnemonic('B');
|
|
||||||
label.addActionListener(mouseEvent -> this
|
|
||||||
.triggerCollectionDisplayListeners(CollectionType.album, SongProvider.INSTANCE
|
|
||||||
.getAlbums()));
|
|
||||||
this.add(label = this.createButton(langs.getString("collections.genres")));
|
|
||||||
label.setMnemonic('G');
|
|
||||||
label.addActionListener(mouseEvent -> this
|
|
||||||
.triggerCollectionDisplayListeners(CollectionType.genre, SongProvider.INSTANCE
|
|
||||||
.getGenres()));
|
|
||||||
this.add(label = this.createButton(langs.getString("collections.years")));
|
|
||||||
label.setMnemonic('Y');
|
|
||||||
label.addActionListener(mouseEvent -> this
|
|
||||||
.triggerCollectionDisplayListeners(CollectionType.year, SongProvider.INSTANCE
|
|
||||||
.getYears()));
|
|
||||||
this.add(new JLabel("\u23AF".repeat(6)));
|
this.add(new JLabel("\u23AF".repeat(6)));
|
||||||
this.add(label = this.createButton(langs.getString("collections.playlists")));
|
this.add(label = this.createButton(Interface.getInstance().actions.get("view.playlists")));
|
||||||
label.setMnemonic('P');
|
|
||||||
this.add(new JLabel("\u23AF".repeat(6)));
|
this.add(new JLabel("\u23AF".repeat(6)));
|
||||||
this.add(label = this.createButton(langs.getString("actions.external.add.title")));
|
this.add(label = this.createButton(Interface.getInstance().actions.get("addExternal")));
|
||||||
label.setMnemonic('E');
|
|
||||||
label.addActionListener(mouseEvent -> this.addNewSong());
|
|
||||||
|
|
||||||
addMouseListener(new MouseAdapter()
|
addMouseListener(new MouseAdapter()
|
||||||
{
|
{
|
||||||
@@ -123,7 +101,16 @@ public class Collections extends JPanel
|
|||||||
|
|
||||||
private JButton createButton(String text)
|
private JButton createButton(String text)
|
||||||
{
|
{
|
||||||
JButton label = new JButton(text);
|
return setButton(new JButton(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
private JButton createButton(Action action)
|
||||||
|
{
|
||||||
|
return setButton(new JButton(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private JButton setButton(JButton label)
|
||||||
|
{
|
||||||
label.setFocusPainted(true);
|
label.setFocusPainted(true);
|
||||||
label.setMargin(new Insets(0, 0, 0, 0));
|
label.setMargin(new Insets(0, 0, 0, 0));
|
||||||
label.setContentAreaFilled(false);
|
label.setContentAreaFilled(false);
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import edu.regis.universeplayer.data.*;
|
|||||||
import edu.regis.universeplayer.localPlayer.LocalPlayer;
|
import edu.regis.universeplayer.localPlayer.LocalPlayer;
|
||||||
|
|
||||||
import net.harawata.appdirs.AppDirsFactory;
|
import net.harawata.appdirs.AppDirsFactory;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -39,12 +41,17 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
// Locale.setDefault(new Locale("es", "ES"));
|
// Locale.setDefault(new Locale("es", "ES"));
|
||||||
// }
|
// }
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Interface.class);
|
private static final Logger logger = LoggerFactory.getLogger(Interface.class);
|
||||||
private static final ResourceBundle langs = ResourceBundle.getBundle("lang.interface", Locale.getDefault());
|
private static final ResourceBundle langs = ResourceBundle
|
||||||
|
.getBundle("lang.interface", Locale.getDefault());
|
||||||
|
|
||||||
|
private static Interface INSTANCE;
|
||||||
|
|
||||||
private static File dataDir;
|
private static File dataDir;
|
||||||
private static File commDir;
|
private static File commDir;
|
||||||
private static File configDir;
|
private static File configDir;
|
||||||
|
|
||||||
|
public final ActionMap actions = new ActionMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the panel containing links to different collection views.
|
* A reference to the panel containing links to different collection views.
|
||||||
*/
|
*/
|
||||||
@@ -76,6 +83,11 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
private final ArrayList<Player<?>> players = new ArrayList<>();
|
private final ArrayList<Player<?>> players = new ArrayList<>();
|
||||||
private int currentPlayer = -1;
|
private int currentPlayer = -1;
|
||||||
|
|
||||||
|
public static Interface getInstance()
|
||||||
|
{
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
Thread browserThread;
|
Thread browserThread;
|
||||||
@@ -91,15 +103,15 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
*/
|
*/
|
||||||
logger.info("Starting application");
|
logger.info("Starting application");
|
||||||
|
|
||||||
browser = Browser.createBrowser();
|
|
||||||
browserThread = new Thread(browser);
|
|
||||||
browserThread.start();
|
|
||||||
|
|
||||||
inter = new Interface();
|
inter = new Interface();
|
||||||
inter.setSize(700, 500);
|
inter.setSize(700, 500);
|
||||||
SongProvider.INSTANCE.addUpdateListener(inter);
|
SongProvider.INSTANCE.addUpdateListener(inter);
|
||||||
inter.setVisible(true);
|
inter.setVisible(true);
|
||||||
|
|
||||||
|
browser = Browser.createBrowser();
|
||||||
|
browserThread = new Thread(browser);
|
||||||
|
browserThread.start();
|
||||||
|
|
||||||
Player.REGISTERED_PLAYERS.put(LocalSong.class, new LocalPlayer());
|
Player.REGISTERED_PLAYERS.put(LocalSong.class, new LocalPlayer());
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -135,26 +147,31 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
logger.error("Could not open browser background", e);
|
logger.error("Could not open browser background", e);
|
||||||
JOptionPane.showMessageDialog(inter, e, langs.getString("error.browser.launch"), JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(inter, e, langs
|
||||||
|
.getString("error.browser.launch"), JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
logger.error("Could not open browser background", e);
|
logger.error("Could not open browser background", e);
|
||||||
JOptionPane.showMessageDialog(inter != null && inter.isVisible() ? inter : null, e, langs.getString("error.generic"), JOptionPane.ERROR_MESSAGE);
|
JOptionPane
|
||||||
|
.showMessageDialog(inter != null && inter.isVisible() ? inter : null, e, langs
|
||||||
|
.getString("error.generic"), JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the data storage directory for the application, creating it if
|
* Obtains the data storage directory for the application, creating it if
|
||||||
* needed.
|
* needed.
|
||||||
|
*
|
||||||
* @return The data storage directory.
|
* @return The data storage directory.
|
||||||
*/
|
*/
|
||||||
public static File getDataDir()
|
public static File getDataDir()
|
||||||
{
|
{
|
||||||
if (dataDir == null)
|
if (dataDir == null)
|
||||||
{
|
{
|
||||||
dataDir = new File(AppDirsFactory.getInstance().getUserDataDir("universalmusic", null, null, true));
|
dataDir = new File(AppDirsFactory.getInstance()
|
||||||
|
.getUserDataDir("universalmusic", null, null, true));
|
||||||
if (!dataDir.exists())
|
if (!dataDir.exists())
|
||||||
{
|
{
|
||||||
if (!dataDir.mkdir())
|
if (!dataDir.mkdir())
|
||||||
@@ -169,13 +186,15 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
/**
|
/**
|
||||||
* Obtains the configuration directory for the application, creating it if
|
* Obtains the configuration directory for the application, creating it if
|
||||||
* needed.
|
* needed.
|
||||||
|
*
|
||||||
* @return The configuration directory.
|
* @return The configuration directory.
|
||||||
*/
|
*/
|
||||||
public static File getConfigDir()
|
public static File getConfigDir()
|
||||||
{
|
{
|
||||||
if (configDir == null)
|
if (configDir == null)
|
||||||
{
|
{
|
||||||
configDir = new File(AppDirsFactory.getInstance().getUserConfigDir("universalmusic", null, null, true));
|
configDir = new File(AppDirsFactory.getInstance()
|
||||||
|
.getUserConfigDir("universalmusic", null, null, true));
|
||||||
if (!configDir.exists())
|
if (!configDir.exists())
|
||||||
{
|
{
|
||||||
if (!configDir.mkdir())
|
if (!configDir.mkdir())
|
||||||
@@ -189,13 +208,15 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the directory for memory mapped files
|
* Obtains the directory for memory mapped files
|
||||||
|
*
|
||||||
* @return The communications storage directory.
|
* @return The communications storage directory.
|
||||||
*/
|
*/
|
||||||
public static File getCommDir()
|
public static File getCommDir()
|
||||||
{
|
{
|
||||||
if (commDir == null)
|
if (commDir == null)
|
||||||
{
|
{
|
||||||
commDir = new File(AppDirsFactory.getInstance().getSharedDir("universalmusic", null, null), "comm");
|
commDir = new File(AppDirsFactory.getInstance()
|
||||||
|
.getSharedDir("universalmusic", null, null), "comm");
|
||||||
if (!commDir.getParentFile().exists())
|
if (!commDir.getParentFile().exists())
|
||||||
{
|
{
|
||||||
if (!commDir.getParentFile().mkdir())
|
if (!commDir.getParentFile().mkdir())
|
||||||
@@ -220,6 +241,283 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
public Interface()
|
public Interface()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
INSTANCE = this;
|
||||||
|
|
||||||
|
this.initActions();
|
||||||
|
|
||||||
|
this.collectionTypes = new Collections();
|
||||||
|
this.controls = new PlayerControls();
|
||||||
|
this.queueList = new QueueList();
|
||||||
|
this.songList = new SongList();
|
||||||
|
this.collectionList = new CollectionList();
|
||||||
|
this.centerView = new JScrollPane(this.songList);
|
||||||
|
|
||||||
|
this.constructWindow();
|
||||||
|
this.setFocusManager();
|
||||||
|
|
||||||
|
this.updateSongs(SongProvider.INSTANCE.getSongs());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initActions()
|
||||||
|
{
|
||||||
|
AbstractAction action;
|
||||||
|
|
||||||
|
this.actions.put("refresh", action = new AbstractAction(langs.getString("actions.refresh"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
|
||||||
|
|
||||||
|
this.actions.put("addExternal", action = new AbstractAction(langs
|
||||||
|
.getString("actions.addExternal"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
InternetSongDialog dialog = new InternetSongDialog(Interface.this);
|
||||||
|
dialog.addWindowListener(new WindowAdapter()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Invoked when a window has been closed.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_E);
|
||||||
|
|
||||||
|
this.actions.put("exit", action = new AbstractAction(langs.getString("actions.exit"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
Interface.this
|
||||||
|
.dispatchEvent(new WindowEvent(Interface.this, WindowEvent.WINDOW_CLOSING));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_X);
|
||||||
|
|
||||||
|
this.actions.put("logs", action = new AbstractAction(langs.getString("actions.logs"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions.put("about", action = new AbstractAction(langs.getString("actions.about"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions
|
||||||
|
.put("view.all", action = new AbstractAction(langs.getString("actions.view.all"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
collectionTypes
|
||||||
|
.triggerSongDisplayListeners(new ArrayList<>(SongProvider.INSTANCE
|
||||||
|
.getSongs()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A);
|
||||||
|
|
||||||
|
this.actions.put("view.artists", action = new AbstractAction(langs
|
||||||
|
.getString("actions.view.artists"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
collectionTypes
|
||||||
|
.triggerCollectionDisplayListeners(CollectionType.albumArtist, SongProvider.INSTANCE
|
||||||
|
.getAlbumArtists());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T);
|
||||||
|
|
||||||
|
this.actions.put("view.albums", action = new AbstractAction(langs
|
||||||
|
.getString("actions.view.albums"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
collectionTypes
|
||||||
|
.triggerCollectionDisplayListeners(CollectionType.album, SongProvider.INSTANCE
|
||||||
|
.getAlbums());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_B);
|
||||||
|
|
||||||
|
this.actions.put("view.genres", action = new AbstractAction(langs
|
||||||
|
.getString("actions.view.genres"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
collectionTypes
|
||||||
|
.triggerCollectionDisplayListeners(CollectionType.genre, SongProvider.INSTANCE
|
||||||
|
.getGenres());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_G);
|
||||||
|
|
||||||
|
this.actions.put("view.years", action = new AbstractAction(langs
|
||||||
|
.getString("actions.view.years"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
collectionTypes
|
||||||
|
.triggerCollectionDisplayListeners(CollectionType.year, SongProvider.INSTANCE
|
||||||
|
.getYears());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_Y);
|
||||||
|
|
||||||
|
this.actions.put("view.playlists", action = new AbstractAction(langs
|
||||||
|
.getString("actions.view.playlists"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_L);
|
||||||
|
|
||||||
|
this.actions.put("playback.clear", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.clear"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
Queue.getInstance().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
|
||||||
|
|
||||||
|
this.actions.put("playback.play", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.play"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
controls.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions.put("playback.pause", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.pause"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
controls.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions.put("playback.toggle", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.toggle"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
controls.togglePlayback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions.put("playback.skipPrev", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.skipPrev"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
controls.previousSong();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.actions.put("playback.skipNext", action = new AbstractAction(langs
|
||||||
|
.getString("actions.playback.skipNext"))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (this.isEnabled())
|
||||||
|
{
|
||||||
|
controls.nextSong();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void constructWindow()
|
||||||
|
{
|
||||||
|
JMenuBar toolbar;
|
||||||
|
JMenu fileMenu, viewMenu, collectionsMenu, playbackMenu, helpMenu;
|
||||||
|
|
||||||
this.setTitle(langs.getString("title"));
|
this.setTitle(langs.getString("title"));
|
||||||
this.getContentPane().setLayout(new BorderLayout());
|
this.getContentPane().setLayout(new BorderLayout());
|
||||||
@@ -227,41 +525,92 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
this.setFocusCycleRoot(true);
|
this.setFocusCycleRoot(true);
|
||||||
|
|
||||||
this.getContentPane()
|
this.getContentPane()
|
||||||
.add(this.collectionTypes = new Collections(), BorderLayout.LINE_START);
|
.add(this.collectionTypes, BorderLayout.LINE_START);
|
||||||
this.collectionTypes.addFocusListener(this);
|
this.collectionTypes.addFocusListener(this);
|
||||||
this.collectionTypes.addSongDisplayListener(this);
|
this.collectionTypes.addSongDisplayListener(this);
|
||||||
|
|
||||||
this.controls = new PlayerControls();
|
|
||||||
this.controls.addFocusListener(this);
|
this.controls.addFocusListener(this);
|
||||||
this.getContentPane().add(controls, BorderLayout.PAGE_END);
|
this.getContentPane().add(controls, BorderLayout.PAGE_END);
|
||||||
|
|
||||||
this.queueList = new QueueList();
|
|
||||||
this.queueList.addFocusListener(this);
|
this.queueList.addFocusListener(this);
|
||||||
Queue.getInstance().addQueueChangeListener(this.queueList);
|
Queue.getInstance().addQueueChangeListener(this.queueList);
|
||||||
Queue.getInstance().addSongChangeListener(this.queueList);
|
Queue.getInstance().addSongChangeListener(this.queueList);
|
||||||
this.getContentPane().add(queueList, BorderLayout.LINE_END);
|
this.getContentPane().add(queueList, BorderLayout.LINE_END);
|
||||||
|
|
||||||
this.songList = new SongList();
|
|
||||||
this.songList.addFocusListener(this);
|
this.songList.addFocusListener(this);
|
||||||
this.collectionList = new CollectionList();
|
|
||||||
this.collectionList.addSongDisplayListener(this);
|
this.collectionList.addSongDisplayListener(this);
|
||||||
|
|
||||||
this.centerView = new JScrollPane(this.songList);
|
|
||||||
this.getContentPane().add(this.centerView, BorderLayout.CENTER);
|
this.getContentPane().add(this.centerView, BorderLayout.CENTER);
|
||||||
this.componentResized(null);
|
this.componentResized(null);
|
||||||
|
|
||||||
|
toolbar = new JMenuBar();
|
||||||
|
|
||||||
|
fileMenu = new JMenu(langs.getString("menu.file.title"));
|
||||||
|
fileMenu.setMnemonic(KeyEvent.VK_F);
|
||||||
|
toolbar.add(fileMenu);
|
||||||
|
|
||||||
|
viewMenu = new JMenu(langs.getString("menu.view.title"));
|
||||||
|
viewMenu.setMnemonic(KeyEvent.VK_V);
|
||||||
|
toolbar.add(viewMenu);
|
||||||
|
|
||||||
|
collectionsMenu = new JMenu(langs.getString("menu.view.collections"));
|
||||||
|
collectionsMenu.setMnemonic(KeyEvent.VK_C);
|
||||||
|
viewMenu.add(collectionsMenu);
|
||||||
|
|
||||||
|
playbackMenu = new JMenu(langs.getString("menu.playback.title"));
|
||||||
|
playbackMenu.setMnemonic(KeyEvent.VK_P);
|
||||||
|
toolbar.add(playbackMenu);
|
||||||
|
|
||||||
|
helpMenu = new JMenu(langs.getString("menu.help.title"));
|
||||||
|
helpMenu.setMnemonic(KeyEvent.VK_H);
|
||||||
|
toolbar.add(helpMenu);
|
||||||
|
|
||||||
|
fileMenu.add(new JMenuItem(actions.get("refresh")));
|
||||||
|
|
||||||
|
fileMenu.add(actions.get("addExternal"));
|
||||||
|
|
||||||
|
fileMenu.add(new JMenuItem(actions.get("exit")));
|
||||||
|
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.all")));
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.artists")));
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.albums")));
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.genres")));
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.years")));
|
||||||
|
collectionsMenu.add(new JMenuItem(actions.get("view.playlists")));
|
||||||
|
|
||||||
|
playbackMenu.add(new JMenuItem(actions.get("playback.clear")));
|
||||||
|
playbackMenu.addSeparator();
|
||||||
|
playbackMenu.add(new JMenuItem(actions.get("playback.toggle")));
|
||||||
|
playbackMenu.add(new JMenuItem(actions.get("playback.skipPrev")));
|
||||||
|
playbackMenu.add(new JMenuItem(actions.get("playback.skipNext")));
|
||||||
|
|
||||||
|
helpMenu.add(new JMenuItem(actions.get("logs")));
|
||||||
|
|
||||||
|
helpMenu.add(new JMenuItem(actions.get("about")));
|
||||||
|
|
||||||
|
this.setJMenuBar(toolbar);
|
||||||
|
|
||||||
|
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
this.addComponentListener(this);
|
this.addComponentListener(this);
|
||||||
this.addWindowListener(this);
|
this.addWindowListener(this);
|
||||||
this.addFocusListener(this);
|
this.addFocusListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
((SortingFocusTraversalPolicy) this.getFocusTraversalPolicy()).setImplicitDownCycleTraversal(true);
|
protected void setFocusManager()
|
||||||
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Set.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_DOWN, 0), AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_RIGHT, 0)));
|
{
|
||||||
this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Set.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_UP, 0), AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_LEFT, 0)));
|
((SortingFocusTraversalPolicy) this.getFocusTraversalPolicy())
|
||||||
this.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, Set.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0)));
|
.setImplicitDownCycleTraversal(true);
|
||||||
this.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, Set.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)));
|
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Set
|
||||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_DOWN, 0), AWTKeyStroke
|
||||||
|
.getAWTKeyStroke(KeyEvent.VK_RIGHT, 0)));
|
||||||
this.updateSongs(SongProvider.INSTANCE.getSongs());
|
this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Set
|
||||||
|
.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_UP, 0), AWTKeyStroke
|
||||||
|
.getAWTKeyStroke(KeyEvent.VK_LEFT, 0)));
|
||||||
|
this.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, Set
|
||||||
|
.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0)));
|
||||||
|
this.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, Set
|
||||||
|
.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -343,7 +692,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
@Override
|
@Override
|
||||||
public void windowDeactivated(WindowEvent windowEvent)
|
public void windowDeactivated(WindowEvent windowEvent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class InternetSongDialog extends JDialog
|
|||||||
c.anchor = GridBagConstraints.WEST;
|
c.anchor = GridBagConstraints.WEST;
|
||||||
c.insets = new Insets(0, 2, 5, 2);
|
c.insets = new Insets(0, 2, 5, 2);
|
||||||
|
|
||||||
this.getContentPane().add(label = new JLabel(langs.getString("actions.external.add.url")), c);
|
this.getContentPane().add(label = new JLabel(langs.getString("actions.addExternal.url")), c);
|
||||||
this.urlBox = new JTextField();
|
this.urlBox = new JTextField();
|
||||||
this.urlBox.addFocusListener(new FocusAdapter()
|
this.urlBox.addFocusListener(new FocusAdapter()
|
||||||
{
|
{
|
||||||
@@ -76,7 +76,7 @@ public class InternetSongDialog extends JDialog
|
|||||||
|
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(label = new JLabel(langs.getString("actions.external.add.song")), c);
|
this.getContentPane().add(label = new JLabel(langs.getString("actions.addExternal.song")), c);
|
||||||
this.titleBox = new JTextField();
|
this.titleBox = new JTextField();
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(this.titleBox, c);
|
this.getContentPane().add(this.titleBox, c);
|
||||||
@@ -84,7 +84,7 @@ public class InternetSongDialog extends JDialog
|
|||||||
|
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(label = new JLabel(langs.getString("actions.external.add.album")), c);
|
this.getContentPane().add(label = new JLabel(langs.getString("actions.addExternal.album")), c);
|
||||||
this.albumBox = new JTextField();
|
this.albumBox = new JTextField();
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(this.albumBox, c);
|
this.getContentPane().add(this.albumBox, c);
|
||||||
@@ -92,7 +92,7 @@ public class InternetSongDialog extends JDialog
|
|||||||
|
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(label = new JLabel(langs.getString("actions.external.add.artists")), c);
|
this.getContentPane().add(label = new JLabel(langs.getString("actions.addExternal.artists")), c);
|
||||||
this.artistBox = new JTextField();
|
this.artistBox = new JTextField();
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(this.artistBox, c);
|
this.getContentPane().add(this.artistBox, c);
|
||||||
@@ -100,7 +100,7 @@ public class InternetSongDialog extends JDialog
|
|||||||
|
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(label = new JLabel(langs.getString("actions.external.add.genre")), c);
|
this.getContentPane().add(label = new JLabel(langs.getString("actions.addExternal.genre")), c);
|
||||||
this.genreBox = new JTextField();
|
this.genreBox = new JTextField();
|
||||||
c.gridy = ++y;
|
c.gridy = ++y;
|
||||||
this.getContentPane().add(this.genreBox, c);
|
this.getContentPane().add(this.genreBox, c);
|
||||||
|
|||||||
@@ -72,31 +72,31 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
|||||||
buttonCont = new JPanel(buttonLayout);
|
buttonCont = new JPanel(buttonLayout);
|
||||||
this.add(buttonCont);
|
this.add(buttonCont);
|
||||||
|
|
||||||
this.prevButton = new JButton();
|
this.prevButton = new JButton(Interface.getInstance().actions.get("playback.skipPrev"));
|
||||||
|
this.prevButton.setText("");
|
||||||
icon = new ImageIcon(this.getClass()
|
icon = new ImageIcon(this.getClass()
|
||||||
.getResource("/gui/icons/skipPrev.png"), "Previous Button");
|
.getResource("/gui/icons/skipPrev.png"), "Previous Button");
|
||||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||||
this.prevButton.setIcon(icon);
|
this.prevButton.setIcon(icon);
|
||||||
this.prevButton.setPreferredSize(BUTTON_SIZE);
|
this.prevButton.setPreferredSize(BUTTON_SIZE);
|
||||||
this.prevButton.addActionListener(actionEvent -> this.previousSong());
|
|
||||||
buttonCont.add(this.prevButton);
|
buttonCont.add(this.prevButton);
|
||||||
|
|
||||||
this.playButton = new JButton();
|
this.playButton = new JButton(Interface.getInstance().actions.get("playback.toggle"));
|
||||||
|
this.playButton.setText("");
|
||||||
PAUSE_ICON = icon = new ImageIcon(this.getClass().getResource("/gui/icons/pause.png"), "Pause Button");
|
PAUSE_ICON = icon = new ImageIcon(this.getClass().getResource("/gui/icons/pause.png"), "Pause Button");
|
||||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||||
PLAY_ICON = icon = new ImageIcon(this.getClass().getResource("/gui/icons/play.png"), "Play Button");
|
PLAY_ICON = icon = new ImageIcon(this.getClass().getResource("/gui/icons/play.png"), "Play Button");
|
||||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||||
this.playButton.setIcon(icon);
|
this.playButton.setIcon(icon);
|
||||||
this.playButton.setPreferredSize(BUTTON_SIZE);
|
this.playButton.setPreferredSize(BUTTON_SIZE);
|
||||||
this.playButton.addActionListener(actionEvent -> this.togglePlayback());
|
|
||||||
buttonCont.add(this.playButton);
|
buttonCont.add(this.playButton);
|
||||||
|
|
||||||
this.nextButton = new JButton();
|
this.nextButton = new JButton(Interface.getInstance().actions.get("playback.skipNext"));
|
||||||
|
this.nextButton.setText("");
|
||||||
icon = new ImageIcon(this.getClass().getResource("/gui/icons/skipNext.png"), "Next Button");
|
icon = new ImageIcon(this.getClass().getResource("/gui/icons/skipNext.png"), "Next Button");
|
||||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||||
this.nextButton.setIcon(icon);
|
this.nextButton.setIcon(icon);
|
||||||
this.nextButton.setPreferredSize(BUTTON_SIZE);
|
this.nextButton.setPreferredSize(BUTTON_SIZE);
|
||||||
this.nextButton.addActionListener(actionEvent -> this.nextSong());
|
|
||||||
buttonCont.add(this.nextButton);
|
buttonCont.add(this.nextButton);
|
||||||
|
|
||||||
progressLayout = new SpringLayout();
|
progressLayout = new SpringLayout();
|
||||||
@@ -172,10 +172,65 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
|||||||
this.triggerCommandListeners(PlaybackCommand.SEEK, value);
|
this.triggerCommandListeners(PlaybackCommand.SEEK, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void play()
|
||||||
|
{
|
||||||
|
this.service.execute(() -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (this.currentPlayer != null)
|
||||||
|
{
|
||||||
|
switch ((PlaybackStatus) this.currentPlayer.getStatus().get())
|
||||||
|
{
|
||||||
|
case PAUSED -> this.currentPlayer.play();
|
||||||
|
case STOPPED, EMPTY -> {
|
||||||
|
if (Queue.getInstance().size() > 0)
|
||||||
|
{
|
||||||
|
if (Queue.getInstance().getCurrentSong() == null)
|
||||||
|
{
|
||||||
|
Queue.getInstance().skipToSong(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.currentPlayer.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ExecutionException | InterruptedException e)
|
||||||
|
{
|
||||||
|
logger.error("Could not get current playback status", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.triggerCommandListeners(PlaybackCommand.PLAY, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void pause()
|
||||||
|
{
|
||||||
|
this.service.execute(() -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (this.currentPlayer != null)
|
||||||
|
{
|
||||||
|
switch ((PlaybackStatus) this.currentPlayer.getStatus().get())
|
||||||
|
{
|
||||||
|
case PLAYING -> this.currentPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ExecutionException | InterruptedException e)
|
||||||
|
{
|
||||||
|
logger.error("Could not get current playback status", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.triggerCommandListeners(PlaybackCommand.PAUSE, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the playback of the current song.
|
* Toggles the playback of the current song.
|
||||||
*/
|
*/
|
||||||
private void togglePlayback()
|
protected void togglePlayback()
|
||||||
{
|
{
|
||||||
this.service.execute(() -> {
|
this.service.execute(() -> {
|
||||||
try
|
try
|
||||||
@@ -213,7 +268,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
|||||||
/**
|
/**
|
||||||
* Skips to the next song.
|
* Skips to the next song.
|
||||||
*/
|
*/
|
||||||
private void previousSong()
|
protected void previousSong()
|
||||||
{
|
{
|
||||||
Queue.getInstance().skipPrev();
|
Queue.getInstance().skipPrev();
|
||||||
this.triggerCommandListeners(PlaybackCommand.PREVIOUS, null);
|
this.triggerCommandListeners(PlaybackCommand.PREVIOUS, null);
|
||||||
@@ -222,7 +277,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
|||||||
/**
|
/**
|
||||||
* Skips to the next song.
|
* Skips to the next song.
|
||||||
*/
|
*/
|
||||||
private void nextSong()
|
protected void nextSong()
|
||||||
{
|
{
|
||||||
Queue.getInstance().skipNext();
|
Queue.getInstance().skipNext();
|
||||||
this.triggerCommandListeners(PlaybackCommand.NEXT, null);
|
this.triggerCommandListeners(PlaybackCommand.NEXT, null);
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ public class QueueList extends JPanel implements Queue.SongChangeListener, Queue
|
|||||||
c.gridy = 0;
|
c.gridy = 0;
|
||||||
c.gridwidth = 1;
|
c.gridwidth = 1;
|
||||||
header.add(new JLabel(" ".repeat(20) + langs.getString("interface.queue.title") + " ".repeat(20)), c);
|
header.add(new JLabel(" ".repeat(20) + langs.getString("interface.queue.title") + " ".repeat(20)), c);
|
||||||
this.clearButton = new JButton(langs.getString("actions.clear"));
|
this.clearButton = new JButton(Interface.getInstance().actions.get("playback.clear"));
|
||||||
this.clearButton.addActionListener(e -> Queue.getInstance().clear());
|
|
||||||
c.gridy = 1;
|
c.gridy = 1;
|
||||||
c.gridwidth = 1;
|
c.gridwidth = 1;
|
||||||
header.add(clearButton, c);
|
header.add(clearButton, c);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
title=Universal Music Player
|
title=Universal Music Player
|
||||||
|
|
||||||
|
menu.file.title=File
|
||||||
|
menu.view.title=View
|
||||||
|
menu.view.collections=Collections
|
||||||
|
menu.playback.title=Playback
|
||||||
|
menu.help.title=Help
|
||||||
|
|
||||||
albumInfo.album=Album
|
albumInfo.album=Album
|
||||||
albumInfo.artists=Artists
|
albumInfo.artists=Artists
|
||||||
albumInfo.genres=Genres
|
albumInfo.genres=Genres
|
||||||
albumInfo.year=Year
|
albumInfo.year=Year
|
||||||
|
|
||||||
collections.all=All Songs
|
|
||||||
collections.artists=Artists
|
|
||||||
collections.albums=Albums
|
|
||||||
collections.genres=Genres
|
|
||||||
collections.years=Years
|
|
||||||
collections.playlists=Playlists
|
|
||||||
|
|
||||||
interface.queue.title=Queue
|
interface.queue.title=Queue
|
||||||
|
|
||||||
@@ -19,19 +19,37 @@ actions.confirm=O.K.
|
|||||||
actions.add=Add
|
actions.add=Add
|
||||||
actions.remove=Remove
|
actions.remove=Remove
|
||||||
actions.cancel=Cancel
|
actions.cancel=Cancel
|
||||||
actions.clear=Clear
|
|
||||||
actions.play=Play
|
actions.play=Play
|
||||||
actions.pause=Pause
|
|
||||||
actions.skipNext=Next
|
|
||||||
actions.skipPrev=Previous
|
|
||||||
actions.stop=Stop
|
|
||||||
|
|
||||||
actions.external.add.title=Add External Song
|
actions.addExternal=Add External Song
|
||||||
actions.external.add.url=URL
|
actions.addExternal.url=URL
|
||||||
actions.external.add.song=Song Title
|
actions.addExternal.song=Song Title
|
||||||
actions.external.add.album=Album
|
actions.addExternal.album=Album
|
||||||
actions.external.add.artists=Artists
|
actions.addExternal.artists=Artists
|
||||||
actions.external.add.genre=Genre
|
actions.addExternal.genre=Genre
|
||||||
|
|
||||||
|
actions.refresh=Refresh Song Cache
|
||||||
|
|
||||||
|
actions.exit=Exit
|
||||||
|
|
||||||
|
actions.logs=Show Logs
|
||||||
|
|
||||||
|
actions.about=About
|
||||||
|
|
||||||
|
actions.view.all=All Songs
|
||||||
|
actions.view.artists=Artists
|
||||||
|
actions.view.albums=Albums
|
||||||
|
actions.view.genres=Genres
|
||||||
|
actions.view.years=Years
|
||||||
|
actions.view.playlists=Playlists
|
||||||
|
|
||||||
|
actions.playback.clear=Clear Queue
|
||||||
|
actions.playback.play=Play
|
||||||
|
actions.playback.pause=Pause
|
||||||
|
actions.playback.toggle=Toggle Playback
|
||||||
|
actions.playback.stop=Stop
|
||||||
|
actions.playback.skipPrev=Skip Previously
|
||||||
|
actions.playback.skipNext=Skip Next
|
||||||
|
|
||||||
error.generic=Error!
|
error.generic=Error!
|
||||||
error.browser.launch=Could not open browser background
|
error.browser.launch=Could not open browser background
|
||||||
@@ -1,16 +1,20 @@
|
|||||||
title=Reproductor de música universal
|
title=Reproductor de música universal
|
||||||
|
|
||||||
|
menu.file.title=Archivo
|
||||||
|
|
||||||
|
menu.help.title=Ayuda
|
||||||
|
|
||||||
albumInfo.album=Álbum
|
albumInfo.album=Álbum
|
||||||
albumInfo.artists=Artistas
|
albumInfo.artists=Artistas
|
||||||
albumInfo.genres=Géneros
|
albumInfo.genres=Géneros
|
||||||
albumInfo.year=Año
|
albumInfo.year=Año
|
||||||
|
|
||||||
collections.all=Todas las canciones
|
actions.view.all=Todas las canciones
|
||||||
collections.artists=Artistas
|
actions.view.artists=Artistas
|
||||||
collections.albums=Álbums
|
actions.view.albums=Álbums
|
||||||
collections.genres=Géneros
|
actions.view.genres=Géneros
|
||||||
collections.years=Años
|
actions.view.years=Años
|
||||||
collections.playlists=Listas
|
actions.view.playlists=Listas
|
||||||
|
|
||||||
interface.queue.title=Queue
|
interface.queue.title=Queue
|
||||||
|
|
||||||
@@ -26,12 +30,20 @@ actions.skipNext=Siguiente
|
|||||||
actions.skipPrev=Anteriormente
|
actions.skipPrev=Anteriormente
|
||||||
actions.stop=Detener
|
actions.stop=Detener
|
||||||
|
|
||||||
actions.external.add.title=Añadir canción externa
|
actions.addExternal=Añadir canción externa
|
||||||
actions.external.add.url=URL
|
actions.addExternal.url=URL
|
||||||
actions.external.add.song=Título
|
actions.addExternal.song=Título
|
||||||
actions.external.add.album=Álbum
|
actions.addExternal.album=Álbum
|
||||||
actions.external.add.artists=Artistas
|
actions.addExternal.artists=Artistas
|
||||||
actions.external.add.genre=Género
|
actions.addExternal.genre=Género
|
||||||
|
|
||||||
|
actions.refresh=Actualizar la caché de canciones
|
||||||
|
|
||||||
|
actions.exit=Salir
|
||||||
|
|
||||||
|
actions.logs=Mostrar registros
|
||||||
|
|
||||||
|
actions.about=Sobre nosotros
|
||||||
|
|
||||||
error.generic=¡Error!
|
error.generic=¡Error!
|
||||||
error.browser.launch=No se puede abrir el fondo del navegador
|
error.browser.launch=No se puede abrir el fondo del navegador
|
||||||
Reference in New Issue
Block a user