Improves error handling (foreground still needs testing).
This commit is contained in:
@@ -12,6 +12,7 @@ import edu.regis.universeplayer.browserCommands.*;
|
||||
import edu.regis.universeplayer.data.InternetSong;
|
||||
import edu.regis.universeplayer.data.PlaybackEvent;
|
||||
import edu.regis.universeplayer.data.Song;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -28,14 +29,15 @@ import java.util.concurrent.*;
|
||||
*/
|
||||
public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(BrowserPlayer.class);
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(BrowserPlayer.class);
|
||||
|
||||
private final LinkedList<PlaybackListener> listeners = new LinkedList<>();
|
||||
|
||||
|
||||
private InternetSong currentSong;
|
||||
|
||||
|
||||
private Browser browserRef = null;
|
||||
|
||||
|
||||
private Browser getBrowser()
|
||||
{
|
||||
if (browserRef == null)
|
||||
@@ -56,19 +58,20 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
}
|
||||
return browserRef;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Song getCurrentSong()
|
||||
{
|
||||
return this.currentSong;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Void> loadSong(InternetSong song)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandLoadSong(song.location)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandLoadSong(song.location)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -76,7 +79,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells the browser process to shut down.
|
||||
*/
|
||||
@@ -85,7 +88,8 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
try
|
||||
{
|
||||
QueryFuture<Void> future = new ForwardedFuture(getBrowser().sendObject(new CommandQuit()));
|
||||
QueryFuture<Void> future = new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandQuit()));
|
||||
return future;
|
||||
}
|
||||
catch (IOException e)
|
||||
@@ -94,7 +98,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a listener for playback status updates.
|
||||
*
|
||||
@@ -105,7 +109,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if a listener has been added.
|
||||
*
|
||||
@@ -117,7 +121,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
return this.listeners.contains(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a listener for playback status updates.
|
||||
*
|
||||
@@ -128,13 +132,14 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Void> play()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PLAY)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PLAY)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -142,13 +147,14 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Void> pause()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PAUSE)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PAUSE)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -156,13 +162,14 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Void> togglePlayback()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PAUSE)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandSetPlayback(CommandSetPlayback.Playback.PAUSE)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -170,7 +177,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stops playback of the current song.
|
||||
*/
|
||||
@@ -179,7 +186,8 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandLoadSong((URL) null)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandLoadSong((URL) null)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -187,13 +195,14 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Void> seek(float time)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser().sendObject(new CommandSeek(time)));
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandSeek(time)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -201,7 +210,7 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the player's current playback status.
|
||||
*
|
||||
@@ -215,54 +224,54 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
Future future = getBrowser().sendObject(new QueryStatus());
|
||||
return new QueryFuture<>()
|
||||
{
|
||||
|
||||
|
||||
private CommandReturn<String> getVal() throws ExecutionException, InterruptedException
|
||||
{
|
||||
return ((CommandReturn<String>) future.get());
|
||||
}
|
||||
|
||||
|
||||
private CommandReturn<String> getVal(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
return ((CommandReturn<String>) future.get(timeout, unit));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
|
||||
{
|
||||
return this.getVal().getConfirmation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
return this.getVal(timeout, unit).getConfirmation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning)
|
||||
{
|
||||
return future.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return future.isCancelled();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDone()
|
||||
{
|
||||
return future.isDone();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PlaybackStatus get() throws InterruptedException, ExecutionException
|
||||
{
|
||||
String value = getVal().getReturnValue();
|
||||
return PlaybackStatus.valueOf(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PlaybackStatus get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
@@ -277,19 +286,40 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Float> getCurrentTime()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public QueryFuture<Float> getLength()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Causes the browser to throw an error
|
||||
*
|
||||
* @param forward - Whether the error should be thrown from the foreground
|
||||
* script or the background script.
|
||||
* @return
|
||||
*/
|
||||
public QueryFuture<Void> throwError(boolean forward)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ForwardedFuture(getBrowser()
|
||||
.sendObject(new CommandError(forward)));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
logger.error("Could not send message", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Object object, MessageRunner runner)
|
||||
{
|
||||
@@ -300,62 +330,62 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
|
||||
this.listeners.forEach(l -> l.onPlaybackChanged(status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ForwardedFuture<T> implements QueryFuture<T>
|
||||
{
|
||||
private final Future<T> future;
|
||||
|
||||
|
||||
ForwardedFuture(Future<T> future)
|
||||
{
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
|
||||
private CommandReturn<T> getVal() throws ExecutionException, InterruptedException
|
||||
{
|
||||
return ((CommandReturn<T>) this.future.get());
|
||||
}
|
||||
|
||||
|
||||
private CommandReturn<T> getVal(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
return ((CommandReturn<T>) this.future.get(timeout, unit));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
|
||||
{
|
||||
return this.getVal().getConfirmation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
return this.getVal(timeout, unit).getConfirmation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning)
|
||||
{
|
||||
return this.future.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return this.future.isCancelled();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDone()
|
||||
{
|
||||
return this.future.isDone();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get() throws InterruptedException, ExecutionException
|
||||
{
|
||||
return this.getVal().getReturnValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
|
||||
@@ -7,6 +7,8 @@ package edu.regis.universeplayer.player;
|
||||
import edu.regis.universeplayer.Player;
|
||||
import edu.regis.universeplayer.browser.Browser;
|
||||
import edu.regis.universeplayer.browser.BrowserPlayer;
|
||||
import edu.regis.universeplayer.browserCommands.CommandError;
|
||||
import edu.regis.universeplayer.browserCommands.QueryFuture;
|
||||
import edu.regis.universeplayer.data.InternetSong;
|
||||
import edu.regis.universeplayer.data.Queue;
|
||||
import edu.regis.universeplayer.data.*;
|
||||
@@ -28,9 +30,11 @@ import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* The Interface class serves as the primary GUI that the player interacts with.
|
||||
* The Interface class serves as the primary GUI that the player interacts
|
||||
* with.
|
||||
*
|
||||
* @author William Hubbard
|
||||
* @version 0.1
|
||||
@@ -40,7 +44,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
// static {
|
||||
// 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());
|
||||
|
||||
@@ -119,8 +124,10 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
inter.players.add(browserPlayer = new BrowserPlayer());
|
||||
logger.debug("Sending ping");
|
||||
browser.sendObject("ping");
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(browserPlayer::close));
|
||||
Player.REGISTERED_PLAYERS.put(InternetSong.class, browserPlayer);
|
||||
Runtime.getRuntime()
|
||||
.addShutdownHook(new Thread(browserPlayer::close));
|
||||
Player.REGISTERED_PLAYERS
|
||||
.put(InternetSong.class, browserPlayer);
|
||||
|
||||
// LinkedList<Future<Object>> pingRequests = new LinkedList<>();
|
||||
// for (int i = 0; i < 20; i++)
|
||||
@@ -155,7 +162,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
{
|
||||
logger.error("Could not open browser background", e);
|
||||
JOptionPane
|
||||
.showMessageDialog(inter != null && inter.isVisible() ? inter : null, e, langs
|
||||
.showMessageDialog(inter != null && inter
|
||||
.isVisible() ? inter : null, e, langs
|
||||
.getString("error.generic"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
@@ -221,7 +229,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
{
|
||||
if (!commDir.getParentFile().mkdir())
|
||||
{
|
||||
logger.error("Could not create shared directory {}", commDir.getParent());
|
||||
logger.error("Could not create shared directory {}", commDir
|
||||
.getParent());
|
||||
}
|
||||
}
|
||||
if (!commDir.exists())
|
||||
@@ -262,7 +271,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
{
|
||||
AbstractAction action;
|
||||
|
||||
this.actions.put("refresh", action = new AbstractAction(langs.getString("actions.refresh"))
|
||||
this.actions.put("refresh", action = new AbstractAction(langs
|
||||
.getString("actions.refresh"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
@@ -302,7 +312,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
});
|
||||
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_E);
|
||||
|
||||
this.actions.put("exit", action = new AbstractAction(langs.getString("actions.exit"))
|
||||
this.actions.put("exit", action = new AbstractAction(langs
|
||||
.getString("actions.exit"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
@@ -316,7 +327,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
});
|
||||
action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_X);
|
||||
|
||||
this.actions.put("logs", action = new AbstractAction(langs.getString("actions.logs"))
|
||||
this.actions.put("logs", action = new AbstractAction(langs
|
||||
.getString("actions.logs"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
@@ -330,9 +342,114 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
}
|
||||
}
|
||||
});
|
||||
action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0));
|
||||
action.putValue(Action.ACCELERATOR_KEY, KeyStroke
|
||||
.getKeyStroke(KeyEvent.VK_F12, 0));
|
||||
|
||||
this.actions.put("about", action = new AbstractAction(langs.getString("actions.about"))
|
||||
this.actions.put("debug.error", action =
|
||||
new AbstractAction(langs.getString("actions.debug.error"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
if (this.isEnabled())
|
||||
{
|
||||
new SwingWorker<Void, Void>()
|
||||
{
|
||||
/**
|
||||
* Computes
|
||||
* a
|
||||
* result,
|
||||
* or
|
||||
* throws
|
||||
* an
|
||||
* exception
|
||||
* if
|
||||
* unable
|
||||
* to
|
||||
* do
|
||||
* so.
|
||||
*
|
||||
* <p>
|
||||
* Note
|
||||
* that
|
||||
* this
|
||||
* method
|
||||
* is
|
||||
* executed
|
||||
* only
|
||||
* once.
|
||||
*
|
||||
* <p>
|
||||
* Note:
|
||||
* this
|
||||
* method
|
||||
* is
|
||||
* executed
|
||||
* in
|
||||
* a
|
||||
* background
|
||||
* thread.
|
||||
*
|
||||
* @return the computed result
|
||||
* @throws Exception if unable to compute a result
|
||||
*/
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception
|
||||
{
|
||||
Interface.this.players.stream()
|
||||
.filter(p -> p instanceof BrowserPlayer)
|
||||
.map(p -> (BrowserPlayer) p)
|
||||
.findFirst()
|
||||
.ifPresentOrElse(p -> {
|
||||
logger.debug("Throwing " +
|
||||
"error");
|
||||
QueryFuture<Void> command = p
|
||||
.throwError((false));
|
||||
try
|
||||
{
|
||||
if (!command
|
||||
.getConfirmation()
|
||||
.wasSuccessful())
|
||||
{
|
||||
logger.error("Could not run command",
|
||||
command.getConfirmation()
|
||||
.getError());
|
||||
JOptionPane
|
||||
.showMessageDialog(Interface.this,
|
||||
command.getConfirmation()
|
||||
.getError(),
|
||||
command.getConfirmation()
|
||||
.getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException executionException)
|
||||
{
|
||||
logger.error("Error" +
|
||||
" creating " +
|
||||
"debug " +
|
||||
"message", executionException);
|
||||
JOptionPane
|
||||
.showMessageDialog(Interface.this, executionException
|
||||
.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}, () -> JOptionPane
|
||||
.showMessageDialog(Interface.this, langs
|
||||
.getString("error.browser.null"), langs
|
||||
.getString("error.debug.error"), JOptionPane.ERROR_MESSAGE));
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
});
|
||||
action.putValue(Action.ACCELERATOR_KEY, KeyStroke
|
||||
.getKeyStroke(KeyEvent.VK_F12, 0));
|
||||
|
||||
this.actions.put("about", action = new AbstractAction(langs
|
||||
.getString("actions.about"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
@@ -345,7 +462,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
});
|
||||
|
||||
this.actions
|
||||
.put("view.all", action = new AbstractAction(langs.getString("actions.view.all"))
|
||||
.put("view.all", action = new AbstractAction(langs
|
||||
.getString("actions.view.all"))
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
@@ -521,7 +639,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
protected void constructWindow()
|
||||
{
|
||||
JMenuBar toolbar;
|
||||
JMenu fileMenu, viewMenu, collectionsMenu, playbackMenu, helpMenu;
|
||||
JMenu fileMenu, viewMenu, collectionsMenu, playbackMenu, helpMenu,
|
||||
debugMenu;
|
||||
|
||||
this.setTitle(langs.getString("title"));
|
||||
this.getContentPane().setLayout(new BorderLayout());
|
||||
@@ -569,6 +688,10 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
helpMenu.setMnemonic(KeyEvent.VK_H);
|
||||
toolbar.add(helpMenu);
|
||||
|
||||
debugMenu = new JMenu(langs.getString("menu.debug.title"));
|
||||
debugMenu.setMnemonic(KeyEvent.VK_D);
|
||||
helpMenu.add(debugMenu);
|
||||
|
||||
fileMenu.add(new JMenuItem(actions.get("refresh")));
|
||||
|
||||
fileMenu.add(actions.get("addExternal"));
|
||||
@@ -590,6 +713,9 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
|
||||
helpMenu.add(new JMenuItem(actions.get("logs")));
|
||||
|
||||
helpMenu.add(debugMenu);
|
||||
debugMenu.add(new JMenuItem(actions.get("debug.error")));
|
||||
|
||||
helpMenu.add(new JMenuItem(actions.get("about")));
|
||||
|
||||
this.setJMenuBar(toolbar);
|
||||
@@ -606,15 +732,18 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
((SortingFocusTraversalPolicy) this.getFocusTraversalPolicy())
|
||||
.setImplicitDownCycleTraversal(true);
|
||||
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Set
|
||||
.of(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_DOWN, 0), AWTKeyStroke
|
||||
.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
|
||||
.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)));
|
||||
.of(AWTKeyStroke
|
||||
.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -752,7 +881,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
||||
else
|
||||
{
|
||||
int index = -1;
|
||||
Component[] children = ((Container) e.getComponent()).getComponents();
|
||||
Component[] children = ((Container) e.getComponent())
|
||||
.getComponents();
|
||||
for (int i = 0, l = children.length; index == -1 && i < l; i++)
|
||||
{
|
||||
if (children[i] == e.getOppositeComponent())
|
||||
|
||||
@@ -8,52 +8,63 @@ import edu.regis.universeplayer.PlaybackInfo;
|
||||
import edu.regis.universeplayer.PlaybackListener;
|
||||
import edu.regis.universeplayer.PlaybackStatus;
|
||||
import edu.regis.universeplayer.Player;
|
||||
import edu.regis.universeplayer.browserCommands.CommandConfirmation;
|
||||
import edu.regis.universeplayer.browserCommands.CommandReturn;
|
||||
import edu.regis.universeplayer.browserCommands.QueryFuture;
|
||||
import edu.regis.universeplayer.data.PlaybackEvent;
|
||||
import edu.regis.universeplayer.data.Queue;
|
||||
import edu.regis.universeplayer.data.Song;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
/**
|
||||
* This panel contains the buttons necessary for controlling the playback of audio.
|
||||
* This panel contains the buttons necessary for controlling the playback of
|
||||
* audio.
|
||||
*
|
||||
* @author William Hubbard
|
||||
* @version 0.1
|
||||
*/
|
||||
public class PlayerControls extends JPanel implements Queue.SongChangeListener, PlaybackListener
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(PlayerControls.class);
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(PlayerControls.class);
|
||||
private static final ResourceBundle langs = ResourceBundle
|
||||
.getBundle("lang.interface", Locale.getDefault());
|
||||
private final ImageIcon PLAY_ICON, PAUSE_ICON;
|
||||
|
||||
|
||||
/**
|
||||
* A reference to the song currently playing.
|
||||
*/
|
||||
private Song currentSong = null;
|
||||
private Player currentPlayer = null;
|
||||
|
||||
|
||||
private final JButton playButton;
|
||||
private final JButton nextButton;
|
||||
private final JButton prevButton;
|
||||
private final JProgressBar progress;
|
||||
private final JProgressBar updateProgress;
|
||||
|
||||
|
||||
private final ForkJoinPool service = new ForkJoinPool();
|
||||
|
||||
|
||||
/**
|
||||
* A list of all things interested in knowing when we trigger a command.
|
||||
*/
|
||||
private final LinkedList<PlaybackCommandListener> listeners = new LinkedList<>();
|
||||
|
||||
|
||||
public PlayerControls()
|
||||
{
|
||||
final Dimension BUTTON_SIZE = new Dimension(32, 32);
|
||||
@@ -62,71 +73,84 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
JPanel buttonCont, progressCont;
|
||||
FlowLayout buttonLayout;
|
||||
SpringLayout progressLayout;
|
||||
|
||||
|
||||
SpringLayout layout = new SpringLayout();
|
||||
this.setLayout(layout);
|
||||
this.setFocusable(true);
|
||||
this.setFocusCycleRoot(false);
|
||||
|
||||
|
||||
buttonLayout = new FlowLayout();
|
||||
buttonCont = new JPanel(buttonLayout);
|
||||
this.add(buttonCont);
|
||||
|
||||
this.prevButton = new JButton(Interface.getInstance().actions.get("playback.skipPrev"));
|
||||
|
||||
this.prevButton = new JButton(Interface.getInstance().actions
|
||||
.get("playback.skipPrev"));
|
||||
this.prevButton.setText("");
|
||||
icon = new ImageIcon(this.getClass()
|
||||
.getResource("/gui/icons/skipPrev.png"), "Previous Button");
|
||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||
.getResource("/gui/icons/skipPrev.png"), "Previous Button");
|
||||
icon.setImage(icon.getImage()
|
||||
.getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||
this.prevButton.setIcon(icon);
|
||||
this.prevButton.setPreferredSize(BUTTON_SIZE);
|
||||
buttonCont.add(this.prevButton);
|
||||
|
||||
this.playButton = new JButton(Interface.getInstance().actions.get("playback.toggle"));
|
||||
|
||||
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");
|
||||
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");
|
||||
icon.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||
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));
|
||||
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));
|
||||
this.playButton.setIcon(icon);
|
||||
this.playButton.setPreferredSize(BUTTON_SIZE);
|
||||
buttonCont.add(this.playButton);
|
||||
|
||||
this.nextButton = new JButton(Interface.getInstance().actions.get("playback.skipNext"));
|
||||
|
||||
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.setImage(icon.getImage().getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||
icon = new ImageIcon(this.getClass()
|
||||
.getResource("/gui/icons/skipNext.png"), "Next Button");
|
||||
icon.setImage(icon.getImage()
|
||||
.getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, 0));
|
||||
this.nextButton.setIcon(icon);
|
||||
this.nextButton.setPreferredSize(BUTTON_SIZE);
|
||||
buttonCont.add(this.nextButton);
|
||||
|
||||
|
||||
progressLayout = new SpringLayout();
|
||||
progressCont = new JPanel(progressLayout);
|
||||
this.add(progressCont);
|
||||
|
||||
|
||||
this.progress = new JProgressBar();
|
||||
this.progress.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
seek((float) e.getX() / (float) e.getComponent().getWidth() * ((JProgressBar) e.getComponent()).getMaximum());
|
||||
seek((float) e.getX() / (float) e.getComponent()
|
||||
.getWidth() * ((JProgressBar) e
|
||||
.getComponent()).getMaximum());
|
||||
logger.debug("Changing time");
|
||||
}
|
||||
});
|
||||
this.add(this.progress);
|
||||
|
||||
|
||||
this.updateProgress = new JProgressBar();
|
||||
this.updateProgress.setStringPainted(true);
|
||||
this.setUpdateProgress(0, 0, null);
|
||||
this.add(this.updateProgress);
|
||||
|
||||
|
||||
this.addFocusListener(new FocusAdapter()
|
||||
{
|
||||
@Override
|
||||
public void focusGained(FocusEvent e)
|
||||
{
|
||||
int index = -1;
|
||||
Component[] children = ((Container) e.getComponent()).getComponents();
|
||||
Component[] children = ((Container) e.getComponent())
|
||||
.getComponents();
|
||||
for (int i = 0, l = children.length; index == -1 && i < l; i++)
|
||||
{
|
||||
if (children[i] == e.getOppositeComponent())
|
||||
@@ -144,7 +168,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
layout.putConstraint(SpringLayout.NORTH, buttonCont, 0, SpringLayout.NORTH, this);
|
||||
layout.putConstraint(SpringLayout.WEST, buttonCont, 0, SpringLayout.WEST, this);
|
||||
layout.putConstraint(SpringLayout.EAST, buttonCont, 0, SpringLayout.EAST, this);
|
||||
@@ -153,20 +177,39 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
layout.putConstraint(SpringLayout.EAST, this.progress, 5, SpringLayout.EAST, this);
|
||||
layout.putConstraint(SpringLayout.NORTH, this.updateProgress, 5, SpringLayout.SOUTH, this.progress);
|
||||
layout.putConstraint(SpringLayout.WEST, this.updateProgress, 5, SpringLayout.WEST, this);
|
||||
|
||||
|
||||
layout.putConstraint(SpringLayout.EAST, this, 5, SpringLayout.EAST, this.progress);
|
||||
layout.putConstraint(SpringLayout.EAST, this, 5, SpringLayout.EAST, this.updateProgress);
|
||||
layout.putConstraint(SpringLayout.SOUTH, this, 5, SpringLayout.SOUTH, this.updateProgress);
|
||||
|
||||
|
||||
Queue.getInstance().addSongChangeListener(this);
|
||||
}
|
||||
|
||||
|
||||
private void seek(float value)
|
||||
{
|
||||
this.service.execute(() -> {
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
this.currentPlayer.seek(value);
|
||||
QueryFuture<Void> command = this.currentPlayer.seek(value);
|
||||
try
|
||||
{
|
||||
if (!command.getConfirmation().wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
command.getConfirmation().getError(),
|
||||
command.getConfirmation().getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
command.getConfirmation().getError());
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not run command", e);
|
||||
JOptionPane.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.triggerCommandListeners(PlaybackCommand.SEEK, value);
|
||||
@@ -179,28 +222,49 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
switch ((PlaybackStatus) this.currentPlayer.getStatus().get())
|
||||
QueryFuture<PlaybackStatus> status =
|
||||
this.currentPlayer.getStatus();
|
||||
CommandConfirmation confirmation = status.getConfirmation();
|
||||
if (status.getConfirmation().wasSuccessful())
|
||||
{
|
||||
case PAUSED -> this.currentPlayer.play();
|
||||
case STOPPED, EMPTY -> {
|
||||
if (Queue.getInstance().size() > 0)
|
||||
switch (status.get())
|
||||
{
|
||||
if (Queue.getInstance().getCurrentSong() == null)
|
||||
case PAUSED -> confirmation = this.currentPlayer.play()
|
||||
.getConfirmation();
|
||||
case STOPPED, EMPTY -> {
|
||||
if (Queue.getInstance().size() > 0)
|
||||
{
|
||||
Queue.getInstance().skipToSong(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentPlayer.play();
|
||||
if (Queue.getInstance()
|
||||
.getCurrentSong() == null)
|
||||
{
|
||||
Queue.getInstance().skipToSong(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirmation = this.currentPlayer.play()
|
||||
.getConfirmation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (confirmation != null && !confirmation.wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
confirmation.getError(),
|
||||
confirmation.getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
confirmation.getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not get current playback status", e);
|
||||
JOptionPane.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
this.triggerCommandListeners(PlaybackCommand.PLAY, null);
|
||||
@@ -213,20 +277,39 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
switch ((PlaybackStatus) this.currentPlayer.getStatus().get())
|
||||
QueryFuture<PlaybackStatus> status =
|
||||
this.currentPlayer.getStatus();
|
||||
CommandConfirmation confirmation = status.getConfirmation();
|
||||
if (status.getConfirmation().wasSuccessful())
|
||||
{
|
||||
case PLAYING -> this.currentPlayer.pause();
|
||||
switch (status.get())
|
||||
{
|
||||
case PLAYING -> confirmation =
|
||||
this.currentPlayer.pause().getConfirmation();
|
||||
}
|
||||
}
|
||||
if (confirmation != null && !confirmation.wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
confirmation.getError(),
|
||||
confirmation.getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
confirmation.getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not get current playback status", e);
|
||||
JOptionPane.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
this.triggerCommandListeners(PlaybackCommand.PAUSE, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggles the playback of the current song.
|
||||
*/
|
||||
@@ -237,34 +320,56 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
switch ((PlaybackStatus) this.currentPlayer.getStatus().get())
|
||||
QueryFuture<PlaybackStatus> status =
|
||||
this.currentPlayer.getStatus();
|
||||
CommandConfirmation confirmation = status.getConfirmation();
|
||||
if (status.getConfirmation().wasSuccessful())
|
||||
{
|
||||
case PAUSED -> this.currentPlayer.play();
|
||||
case PLAYING -> this.currentPlayer.pause();
|
||||
case STOPPED, EMPTY -> {
|
||||
if (Queue.getInstance().size() > 0)
|
||||
switch (status.get())
|
||||
{
|
||||
if (Queue.getInstance().getCurrentSong() == null)
|
||||
case PAUSED -> confirmation = this.currentPlayer.play()
|
||||
.getConfirmation();
|
||||
case PLAYING -> confirmation = this.currentPlayer.pause()
|
||||
.getConfirmation();
|
||||
case STOPPED, EMPTY -> {
|
||||
if (Queue.getInstance().size() > 0)
|
||||
{
|
||||
Queue.getInstance().skipToSong(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentPlayer.play();
|
||||
if (Queue.getInstance()
|
||||
.getCurrentSong() == null)
|
||||
{
|
||||
Queue.getInstance().skipToSong(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirmation = this.currentPlayer.play()
|
||||
.getConfirmation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (confirmation != null && !confirmation.wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
confirmation.getError(),
|
||||
confirmation.getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
confirmation.getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not get current playback status", e);
|
||||
JOptionPane.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
this.triggerCommandListeners(PlaybackCommand.PLAY, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Skips to the next song.
|
||||
*/
|
||||
@@ -273,7 +378,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
Queue.getInstance().skipPrev();
|
||||
this.triggerCommandListeners(PlaybackCommand.PREVIOUS, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Skips to the next song.
|
||||
*/
|
||||
@@ -282,7 +387,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
Queue.getInstance().skipNext();
|
||||
this.triggerCommandListeners(PlaybackCommand.NEXT, null);
|
||||
}
|
||||
|
||||
|
||||
void setUpdateProgress(int updated, int toUpdate, String updating)
|
||||
{
|
||||
this.updateProgress.setString(updating);
|
||||
@@ -307,7 +412,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a listener for playback commands.
|
||||
*
|
||||
@@ -317,7 +422,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a playback listener.
|
||||
*
|
||||
@@ -327,7 +432,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Triggers all the command listeners.
|
||||
*
|
||||
@@ -341,7 +446,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
listener.onCommand(command, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSongChange(Queue queue)
|
||||
{
|
||||
@@ -349,14 +454,37 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
this.currentPlayer.stopSong();
|
||||
this.service.execute(() -> {
|
||||
QueryFuture<Void> command = this.currentPlayer.stopSong();
|
||||
try
|
||||
{
|
||||
if (!command.getConfirmation().wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
command.getConfirmation().getError(),
|
||||
command.getConfirmation().getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
command.getConfirmation().getError());
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not get current playback status", e);
|
||||
JOptionPane
|
||||
.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
this.currentSong = queue.getCurrentSong();
|
||||
this.playButton.setIcon(PLAY_ICON);
|
||||
if (this.currentSong != null)
|
||||
{
|
||||
this.currentPlayer = Player.REGISTERED_PLAYERS.get(this.currentSong.getClass());
|
||||
this.currentPlayer = Player.REGISTERED_PLAYERS
|
||||
.get(this.currentSong.getClass());
|
||||
this.progress.setMaximum((int) (this.currentSong.duration / 1000));
|
||||
if (this.currentPlayer != null)
|
||||
{
|
||||
@@ -364,12 +492,37 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
{
|
||||
this.currentPlayer.addPlaybackListener(this);
|
||||
}
|
||||
this.currentPlayer.loadSong(this.currentSong);
|
||||
this.service.execute(() -> {
|
||||
QueryFuture<Void> command =
|
||||
this.currentPlayer.loadSong(this.currentSong);
|
||||
try
|
||||
{
|
||||
if (!command.getConfirmation().wasSuccessful())
|
||||
{
|
||||
JOptionPane.showMessageDialog(this,
|
||||
command.getConfirmation().getError(),
|
||||
command.getConfirmation().getMessage(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
logger.error("Could not run command",
|
||||
command.getConfirmation().getError());
|
||||
}
|
||||
}
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
logger.error("Could not get current playback status", e);
|
||||
JOptionPane
|
||||
.showMessageDialog(this, e.getMessage(), langs
|
||||
.getString(
|
||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
|
||||
// this.currentPlayer.play();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error("No logger found for song {}", this.currentSong.getClass());
|
||||
logger.error("No logger found for song {}", this.currentSong
|
||||
.getClass());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -378,11 +531,12 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
this.progress.setMaximum(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPlaybackChanged(PlaybackEvent status)
|
||||
{
|
||||
if (status.getSource() != null && status.getSource() == this.currentPlayer)
|
||||
if (status.getSource() != null && status
|
||||
.getSource() == this.currentPlayer)
|
||||
{
|
||||
switch (status.getInfo().getStatus())
|
||||
{
|
||||
@@ -391,7 +545,8 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
|
||||
case PAUSED, STOPPED, EMPTY -> this.playButton.setIcon(PLAY_ICON);
|
||||
}
|
||||
this.progress.setValue((int) status.getInfo().getPlayTime());
|
||||
this.progress.setMaximum((int) (status.getInfo().getSong().duration / 1000));
|
||||
this.progress.setMaximum((int) (status.getInfo()
|
||||
.getSong().duration / 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ menu.view.title=View
|
||||
menu.view.collections=Collections
|
||||
menu.playback.title=Playback
|
||||
menu.help.title=Help
|
||||
menu.debug.title=Debugging
|
||||
|
||||
albumInfo.album=Album
|
||||
albumInfo.artists=Artists
|
||||
@@ -42,6 +43,7 @@ actions.refresh=Refresh Song Cache
|
||||
actions.exit=Exit
|
||||
|
||||
actions.logs=Show Logs
|
||||
actions.debug.error=Throw Error
|
||||
|
||||
actions.about=About
|
||||
|
||||
@@ -61,4 +63,7 @@ actions.playback.skipPrev=Skip Previously
|
||||
actions.playback.skipNext=Skip Next
|
||||
|
||||
error.generic=Error!
|
||||
error.browser.launch=Could not open browser background
|
||||
error.command=Could not run command
|
||||
error.debug.error=Could not create error
|
||||
error.browser.launch=Could not open browser background
|
||||
error.browser.null=Could not find browser background
|
||||
Reference in New Issue
Block a user