Moves player logic to its own class, away from Interface

In the future, this will make testing and a CLI environment easier.
This commit is contained in:
Markil3
2021-09-14 16:39:40 -06:00
parent 92ebb75e9d
commit 999f3345cc
24 changed files with 791 additions and 519 deletions

View File

@@ -44,5 +44,5 @@ sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
// Define the main class for the application
mainClassName = defaultPackage + '.player.Interface'
mainClassName = defaultPackage + '.gui.Interface'
//mainClassName = defaultPackage + '.localPlayer.Player'

View File

@@ -0,0 +1,93 @@
package edu.regis.universeplayer;
import net.harawata.appdirs.AppDirsFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
public class ConfigManager
{
private static final Logger logger = LoggerFactory
.getLogger(ConfigManager.class);
private static File dataDir;
private static File commDir;
private static File configDir;
/**
* Obtains the data storage directory for the application, creating it if
* needed.
*
* @return The data storage directory.
*/
public static File getDataDir()
{
if (dataDir == null)
{
dataDir = new File(AppDirsFactory.getInstance()
.getUserDataDir("universalmusic", null, null, true));
if (!dataDir.exists())
{
if (!dataDir.mkdir())
{
logger.error("Could not create data directory {}", dataDir);
}
}
}
return dataDir;
}
/**
* Obtains the configuration directory for the application, creating it if
* needed.
*
* @return The configuration directory.
*/
public static File getConfigDir()
{
if (configDir == null)
{
configDir = new File(AppDirsFactory.getInstance()
.getUserConfigDir("universalmusic", null, null, true));
if (!configDir.exists())
{
if (!configDir.mkdir())
{
logger.error("Could not create configuration directory {}", configDir);
}
}
}
return configDir;
}
/**
* Obtains the directory for memory mapped files
*
* @return The communications storage directory.
*/
public static File getCommDir()
{
if (commDir == null)
{
commDir = new File(AppDirsFactory.getInstance()
.getSharedDir("universalmusic", null, null), "comm");
if (!commDir.getParentFile().exists())
{
if (!commDir.getParentFile().mkdir())
{
logger.error("Could not create shared directory {}", commDir
.getParent());
}
}
if (!commDir.exists())
{
if (!commDir.mkdir())
{
logger.error("Could not create data directory {}", commDir);
}
}
}
return commDir;
}
}

View File

@@ -4,7 +4,8 @@
package edu.regis.universeplayer.data;
import edu.regis.universeplayer.player.Interface;
import edu.regis.universeplayer.ConfigManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,7 +31,8 @@ public class DatabaseManager
if (db == null || db.isClosed())
{
Class.forName("org.sqlite.JDBC");
db = DriverManager.getConnection("jdbc:sqlite:" + new File(Interface.getDataDir().getAbsolutePath(), "universalmusic.db").getAbsolutePath());
db = DriverManager.getConnection("jdbc:sqlite:" + new File(ConfigManager
.getDataDir().getAbsolutePath(), "universalmusic.db").getAbsolutePath());
}
warning = db.getWarnings();
while (warning != null)

View File

@@ -4,8 +4,6 @@
package edu.regis.universeplayer.data;
import edu.regis.universeplayer.player.Interface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -5,8 +5,7 @@
package edu.regis.universeplayer.data;
import edu.regis.universeplayer.PlaybackInfo;
import edu.regis.universeplayer.Player;
import edu.regis.universeplayer.localPlayer.LocalPlayer;
import edu.regis.universeplayer.player.Player;
import java.util.EventObject;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import javax.swing.*;
import javax.swing.border.LineBorder;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import java.awt.*;
import java.awt.event.FocusAdapter;
@@ -14,7 +14,7 @@ import java.util.stream.Collectors;
import javax.swing.*;
import com.wordpress.tips4java.ScrollablePanel;
import edu.regis.universeplayer.ClickListener;
import edu.regis.universeplayer.data.Album;
import edu.regis.universeplayer.data.CollectionType;
import edu.regis.universeplayer.data.Song;

View File

@@ -2,11 +2,10 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Locale;
@@ -16,7 +15,6 @@ import javax.swing.*;
import edu.regis.universeplayer.data.CollectionType;
import edu.regis.universeplayer.data.Song;
import edu.regis.universeplayer.data.SongProvider;
/**
* This panel links to various song collections the player has set up.

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import java.awt.*;

View File

@@ -2,19 +2,17 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import edu.regis.universeplayer.Player;
import edu.regis.universeplayer.player.Player;
import edu.regis.universeplayer.browser.Browser;
import edu.regis.universeplayer.browser.BrowserPlayer;
import edu.regis.universeplayer.browserCommands.CommandError;
import edu.regis.universeplayer.player.BrowserPlayer;
import edu.regis.universeplayer.browserCommands.QueryFuture;
import edu.regis.universeplayer.data.InternetSong;
import edu.regis.universeplayer.data.Queue;
import edu.regis.universeplayer.data.*;
import edu.regis.universeplayer.localPlayer.LocalPlayer;
import net.harawata.appdirs.AppDirsFactory;
import edu.regis.universeplayer.player.LocalPlayer;
import edu.regis.universeplayer.player.PlayerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -23,7 +21,6 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -51,10 +48,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
private static Interface INSTANCE;
private static File dataDir;
private static File commDir;
private static File configDir;
public final ActionMap actions = new ActionMap();
/**
@@ -82,10 +75,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
*/
private final PlayerControls controls;
/**
* A link to the browser.
*/
private final ArrayList<Player<?>> players = new ArrayList<>();
private int currentPlayer = -1;
public static Interface getInstance()
@@ -95,10 +84,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
public static void main(String[] args)
{
Thread browserThread;
Interface inter = null;
Browser browser;
BrowserPlayer browserPlayer;
PlayerManager.getPlayers();
try
{
/*
@@ -112,51 +99,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
inter.setSize(700, 500);
SongProvider.INSTANCE.addUpdateListener(inter);
inter.setVisible(true);
browser = Browser.createBrowser();
browserThread = new Thread(browser);
browserThread.start();
Player.REGISTERED_PLAYERS.put(LocalSong.class, new LocalPlayer());
try
{
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);
// LinkedList<Future<Object>> pingRequests = new LinkedList<>();
// for (int i = 0; i < 20; i++)
// {
// logger.info("Sending ping");
// pingRequests.add(browser.sendObject("ping"));
// }
//
// LinkedList<Future<Object>> toRemove = new LinkedList<>();
// while (pingRequests.size() > 0)
// {
// for (Future<Object> future : pingRequests)
// {
// if (future.isDone())
// {
// logger.info("Receiving {}", future.get());
// toRemove.add(future);
// }
// }
// pingRequests.removeAll(toRemove);
// toRemove.clear();
// }
}
catch (IOException e)
{
logger.error("Could not open browser background", e);
JOptionPane.showMessageDialog(inter, e, langs
.getString("error.browser.launch"), JOptionPane.ERROR_MESSAGE);
}
}
catch (Throwable e)
{
@@ -168,82 +110,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
}
}
/**
* Obtains the data storage directory for the application, creating it if
* needed.
*
* @return The data storage directory.
*/
public static File getDataDir()
{
if (dataDir == null)
{
dataDir = new File(AppDirsFactory.getInstance()
.getUserDataDir("universalmusic", null, null, true));
if (!dataDir.exists())
{
if (!dataDir.mkdir())
{
logger.error("Could not create data directory {}", dataDir);
}
}
}
return dataDir;
}
/**
* Obtains the configuration directory for the application, creating it if
* needed.
*
* @return The configuration directory.
*/
public static File getConfigDir()
{
if (configDir == null)
{
configDir = new File(AppDirsFactory.getInstance()
.getUserConfigDir("universalmusic", null, null, true));
if (!configDir.exists())
{
if (!configDir.mkdir())
{
logger.error("Could not create configuration directory {}", configDir);
}
}
}
return configDir;
}
/**
* Obtains the directory for memory mapped files
*
* @return The communications storage directory.
*/
public static File getCommDir()
{
if (commDir == null)
{
commDir = new File(AppDirsFactory.getInstance()
.getSharedDir("universalmusic", null, null), "comm");
if (!commDir.getParentFile().exists())
{
if (!commDir.getParentFile().mkdir())
{
logger.error("Could not create shared directory {}", commDir
.getParent());
}
}
if (!commDir.exists())
{
if (!commDir.mkdir())
{
logger.error("Could not create data directory {}", commDir);
}
}
}
return commDir;
}
/**
* Creates an interface
*/
@@ -396,20 +262,10 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
@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));
QueryFuture<Void> command = PlayerManager.getPlayers().throwError(false);
try
{
if (!command
.getConfirmation()
.wasSuccessful())
if (!command.getConfirmation().wasSuccessful())
{
logger.error("Could not run command",
command.getConfirmation()
@@ -435,10 +291,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
.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();
@@ -578,7 +430,7 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
{
if (this.isEnabled())
{
controls.play();
PlayerManager.getPlayers().play();
}
}
});
@@ -591,7 +443,7 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
{
if (this.isEnabled())
{
controls.pause();
PlayerManager.getPlayers().pause();
}
}
});
@@ -604,7 +456,7 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
{
if (this.isEnabled())
{
controls.togglePlayback();
PlayerManager.getPlayers().toggle();
}
}
});
@@ -796,7 +648,7 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
@Override
public void windowClosing(WindowEvent windowEvent)
{
this.players.forEach(Player::close);
PlayerManager.getPlayers().shutdownPlayers();
}
@Override

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import edu.regis.universeplayer.data.InternetSong;
import edu.regis.universeplayer.data.InternetSongProvider;

View File

@@ -1,6 +1,5 @@
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -8,9 +7,7 @@ import org.slf4j.LoggerFactory;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
@@ -18,16 +15,10 @@ import java.awt.event.WindowEvent;
import java.util.Comparator;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.AbstractAction;
import javax.swing.Box;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
/**
* Contains possible playback commands that the play can send.

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import java.util.EventListener;

View File

@@ -2,18 +2,17 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import edu.regis.universeplayer.PlaybackInfo;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
import edu.regis.universeplayer.Player;
import edu.regis.universeplayer.player.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 edu.regis.universeplayer.player.PlayerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,12 +45,6 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
.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;
@@ -183,33 +176,34 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
layout.putConstraint(SpringLayout.SOUTH, this, 5, SpringLayout.SOUTH, this.updateProgress);
Queue.getInstance().addSongChangeListener(this);
PlayerManager.getPlayers().addPlaybackListener(this);
}
private void seek(float value)
{
this.service.execute(() -> {
if (this.currentPlayer != null)
{
QueryFuture<Void> command = this.currentPlayer.seek(value);
QueryFuture<Void> command = PlayerManager.getPlayers().seek(value);
try
{
if (!command.getConfirmation().wasSuccessful())
if (command != null && !command.getConfirmation()
.wasSuccessful())
{
logger.error("Could not run command",
command.getConfirmation().getError());
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);
}
logger.error("Could not run command",
e);
JOptionPane.showMessageDialog(this,
e,
e.getMessage(),
JOptionPane.ERROR_MESSAGE);
}
});
this.triggerCommandListeners(PlaybackCommand.SEEK, value);
@@ -219,17 +213,16 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
{
this.service.execute(() -> {
try
{
if (this.currentPlayer != null)
{
QueryFuture<PlaybackStatus> status =
this.currentPlayer.getStatus();
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
{
switch (status.get())
{
case PAUSED -> confirmation = this.currentPlayer.play()
case PAUSED -> confirmation = PlayerManager.getPlayers()
.play()
.getConfirmation();
case STOPPED, EMPTY -> {
if (Queue.getInstance().size() > 0)
@@ -241,7 +234,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
}
else
{
confirmation = this.currentPlayer.play()
confirmation = PlayerManager.getPlayers().play()
.getConfirmation();
}
}
@@ -250,13 +243,12 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
}
if (confirmation != null && !confirmation.wasSuccessful())
{
logger.error("Could not run command",
confirmation.getError());
JOptionPane.showMessageDialog(this,
confirmation.getError(),
confirmation.getMessage(),
JOptionPane.ERROR_MESSAGE);
logger.error("Could not run command",
confirmation.getError());
}
}
}
catch (ExecutionException | InterruptedException e)
@@ -274,29 +266,27 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
{
this.service.execute(() -> {
try
{
if (this.currentPlayer != null)
{
QueryFuture<PlaybackStatus> status =
this.currentPlayer.getStatus();
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
{
switch (status.get())
{
case PLAYING -> confirmation =
this.currentPlayer.pause().getConfirmation();
PlayerManager.getPlayers().pause()
.getConfirmation();
}
}
if (confirmation != null && !confirmation.wasSuccessful())
{
logger.error("Could not run command",
confirmation.getError());
JOptionPane.showMessageDialog(this,
confirmation.getError(),
confirmation.getMessage(),
JOptionPane.ERROR_MESSAGE);
logger.error("Could not run command",
confirmation.getError());
}
}
}
catch (ExecutionException | InterruptedException e)
@@ -317,19 +307,19 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
{
this.service.execute(() -> {
try
{
if (this.currentPlayer != null)
{
QueryFuture<PlaybackStatus> status =
this.currentPlayer.getStatus();
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
{
switch (status.get())
{
case PAUSED -> confirmation = this.currentPlayer.play()
case PAUSED -> confirmation = PlayerManager.getPlayers()
.play()
.getConfirmation();
case PLAYING -> confirmation = this.currentPlayer.pause()
case PLAYING -> confirmation = PlayerManager.getPlayers()
.pause()
.getConfirmation();
case STOPPED, EMPTY -> {
if (Queue.getInstance().size() > 0)
@@ -341,7 +331,7 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
}
else
{
confirmation = this.currentPlayer.play()
confirmation = PlayerManager.getPlayers().play()
.getConfirmation();
}
}
@@ -358,7 +348,6 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
confirmation.getError());
}
}
}
catch (ExecutionException | InterruptedException e)
{
logger.error("Could not get current playback status", e);
@@ -449,15 +438,25 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
@Override
public void onSongChange(Queue queue)
{
if (this.currentSong != null)
{
if (this.currentPlayer != null)
{
this.service.execute(() -> {
QueryFuture<Void> command = this.currentPlayer.stopSong();
QueryFuture<Void> command = PlayerManager.getPlayers().stopSong();
try
{
if (command != null && !command.getConfirmation().wasSuccessful())
{
JOptionPane.showMessageDialog(this,
command.getConfirmation().getError(),
command.getConfirmation().getMessage(),
JOptionPane.ERROR_MESSAGE);
logger.error("Could not run command",
command.getConfirmation().getError());
}
else
{
command =
PlayerManager.getPlayers()
.playSong(queue.getCurrentSong());
if (!command.getConfirmation().wasSuccessful())
{
JOptionPane.showMessageDialog(this,
@@ -467,76 +466,31 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
logger.error("Could not run command",
command.getConfirmation().getError());
}
}
catch (ExecutionException | InterruptedException e)
else
{
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();
SwingUtilities.invokeLater(() -> {
this.playButton.setIcon(PLAY_ICON);
if (this.currentSong != null)
{
this.currentPlayer = Player.REGISTERED_PLAYERS
.get(this.currentSong.getClass());
this.progress.setMaximum((int) (this.currentSong.duration / 1000));
if (this.currentPlayer != null)
{
if (!this.currentPlayer.hasPlaybackListener(this))
{
this.currentPlayer.addPlaybackListener(this);
}
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.progress.setMaximum((int) (PlayerManager
.getPlayers()
.getCurrentSong().duration / 1000));
});
// this.currentPlayer.play();
}
else
}
}
catch (ExecutionException | InterruptedException e)
{
logger.error("No logger found for song {}", this.currentSong
.getClass());
}
}
else
{
this.currentPlayer = null;
this.progress.setMaximum(0);
logger.error("Could not get current playback status", e);
JOptionPane
.showMessageDialog(this, e.getMessage(), langs
.getString(
"error.command"), JOptionPane.ERROR_MESSAGE);
}
});
}
@Override
public void onPlaybackChanged(PlaybackEvent status)
{
if (status.getSource() != null && status
.getSource() == this.currentPlayer)
{
switch (status.getInfo().getStatus())
{
@@ -548,5 +502,4 @@ public class PlayerControls extends JPanel implements Queue.SongChangeListener,
this.progress.setMaximum((int) (status.getInfo()
.getSong().duration / 1000));
}
}
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import com.wordpress.tips4java.ScrollablePanel;
import edu.regis.universeplayer.ClickListener;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import java.util.Collection;
import java.util.EventListener;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.player;
package edu.regis.universeplayer.gui;
import com.wordpress.tips4java.ScrollablePanel;

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.localPlayer;
package edu.regis.universeplayer.player;
import java.io.IOException;
import java.io.InputStream;

View File

@@ -2,12 +2,12 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.browser;
package edu.regis.universeplayer.player;
import edu.regis.universeplayer.PlaybackInfo;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
import edu.regis.universeplayer.Player;
import edu.regis.universeplayer.browser.Browser;
import edu.regis.universeplayer.browserCommands.*;
import edu.regis.universeplayer.data.InternetSong;
import edu.regis.universeplayer.data.PlaybackEvent;
@@ -59,6 +59,22 @@ public class BrowserPlayer implements Player<InternetSong>, UpdateListener
return browserRef;
}
public BrowserPlayer()
{
Thread browserThread = new Thread(() -> {
try
{
this.browserRef = Browser.createBrowser();
this.browserRef.run();
}
catch (IOException | InterruptedException e)
{
logger.error("Could not initialize browser", e);
}
});
browserThread.start();
}
@Override
public Song getCurrentSong()
{

View File

@@ -1,20 +1,22 @@
/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.localPlayer;
package edu.regis.universeplayer.player;
import com.intervigil.wave.WaveReader;
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.QueryFuture;
import edu.regis.universeplayer.data.LocalSong;
import edu.regis.universeplayer.data.PlaybackEvent;
import edu.regis.universeplayer.data.Song;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.media.MediaRef;
import uk.co.caprica.vlcj.media.TrackType;
@@ -24,6 +26,7 @@ import uk.co.caprica.vlcj.player.base.StatusApi;
import uk.co.caprica.vlcj.player.component.AudioPlayerComponent;
import javax.swing.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -39,7 +42,8 @@ import java.util.concurrent.*;
*/
public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
{
private static final Logger logger = LoggerFactory.getLogger(LocalPlayer.class);
private static final Logger logger = LoggerFactory
.getLogger(LocalPlayer.class);
private final MediaPlayerFactory playerFactory;
private final AudioPlayerComponent player;
@@ -73,7 +77,8 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
}
/**
* Saves the current file as a WAVE file somewhere else. This method is meant for testing only.
* Saves the current file as a WAVE file somewhere else. This method is
* meant for testing only.
*
* @param file - The file to save to.
*/
@@ -120,21 +125,35 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
this.stopSong();
}
this.currentSong = song;
this.player.mediaPlayer().media().play(song.file.getAbsolutePath());
if (!this.player.mediaPlayer().media()
.play(song.file.getAbsolutePath()))
{
return new NullFuture<>(new RuntimeException("Could not play " +
"song " + song));
}
else
{
return new NullFuture<>();
}
}
@Override
public QueryFuture<Void> play()
{
this.player.mediaPlayer().submit((WrappedRunnable) () -> this.player.mediaPlayer().controls().play());
this.player.mediaPlayer()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.play());
return new NullFuture<>();
}
@Override
public QueryFuture<Void> pause()
{
this.player.mediaPlayer().submit((WrappedRunnable) () -> this.player.mediaPlayer().controls().pause());
this.player.mediaPlayer()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.pause());
return new NullFuture<>();
}
@@ -154,14 +173,19 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
@Override
public QueryFuture<Void> stopSong()
{
this.player.mediaPlayer().submit((WrappedRunnable) () -> this.player.mediaPlayer().controls().stop());
this.player.mediaPlayer()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.stop());
return new NullFuture<>();
}
@Override
public QueryFuture<Void> seek(float time)
{
this.player.mediaPlayer().submit((WrappedRunnable) () -> this.player.mediaPlayer().controls()
this.player.mediaPlayer()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.setTime((long) (time * 1000)));
return new NullFuture<>();
}
@@ -184,13 +208,15 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
@Override
public QueryFuture<Float> getCurrentTime()
{
return new NullFuture<>(this.player.mediaPlayer().status().time() / 1000F);
return new NullFuture<>(this.player.mediaPlayer().status()
.time() / 1000F);
}
@Override
public QueryFuture<Float> getLength()
{
return new NullFuture<>(this.player.mediaPlayer().status().length() / 1000F);
return new NullFuture<>(this.player.mediaPlayer().status()
.length() / 1000F);
}
@Override
@@ -227,7 +253,8 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
* @param file - The file to read
* @return An raw stream for the file
* @throws FileNotFoundException - Thrown should the file not exist.
* @throws IOException - Thrown should an error occur when reading the file
* @throws IOException - Thrown should an error occur when reading
* the file
*/
public static AudioFile getAudioStream(File file) throws IOException
{
@@ -235,12 +262,14 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
}
/**
* Converts any audio file to a stream containing WAV audio file data (courtesy of FFMPEG).
* Converts any audio file to a stream containing WAV audio file data
* (courtesy of FFMPEG).
*
* @param file - The file to convert
* @return An input stream containing the file data
* @throws FileNotFoundException - Thrown should the file not exist.
* @throws IOException - Thrown should an error occur when reading the file
* @throws IOException - Thrown should an error occur when reading
* the file
*/
protected static Process convertFile(File file) throws FileNotFoundException, IOException
{
@@ -304,7 +333,8 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
/**
* The media started playing.
* <p>
* There is no guarantee that a video output has been created at this point.
* There is no guarantee that a video output has been created at this
* point.
*
* @param mediaPlayer media player that raised the event
*/
@@ -312,7 +342,10 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
public void playing(MediaPlayer mediaPlayer)
{
logger.debug("Local player playing.");
SwingUtilities.invokeLater(() -> this.listeners.forEach(playbackListener -> playbackListener.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer.status().time(), PlaybackStatus.PLAYING)))));
SwingUtilities.invokeLater(() -> this.listeners
.forEach(playbackListener -> playbackListener
.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer
.status().time(), PlaybackStatus.PLAYING)))));
}
/**
@@ -324,15 +357,19 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
public void paused(MediaPlayer mediaPlayer)
{
logger.debug("Local player paused.");
SwingUtilities.invokeLater(() -> this.listeners.forEach(playbackListener -> playbackListener.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer.status().time(), PlaybackStatus.PAUSED)))));
SwingUtilities.invokeLater(() -> this.listeners
.forEach(playbackListener -> playbackListener
.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer
.status().time(), PlaybackStatus.PAUSED)))));
}
/**
* Media stopped.
* <p>
* A stopped event may be raised under certain circumstances even if the media player is not playing (e.g. as part
* of the associated media list player sub-item handling). Client applications must therefore be prepared to handle
* such a situation.
* A stopped event may be raised under certain circumstances even if the
* media player is not playing (e.g. as part of the associated media list
* player sub-item handling). Client applications must therefore be prepared
* to handle such a situation.
*
* @param mediaPlayer media player that raised the event
*/
@@ -340,7 +377,10 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
public void stopped(MediaPlayer mediaPlayer)
{
logger.debug("Local player stopped prematurely.");
SwingUtilities.invokeLater(() -> this.listeners.forEach(playbackListener -> playbackListener.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer.status().time(), PlaybackStatus.STOPPED)))));
SwingUtilities.invokeLater(() -> this.listeners
.forEach(playbackListener -> playbackListener
.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer
.status().time(), PlaybackStatus.STOPPED)))));
}
/**
@@ -374,7 +414,10 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
public void finished(MediaPlayer mediaPlayer)
{
logger.debug("Local player finished.");
SwingUtilities.invokeLater(() -> this.listeners.forEach(playbackListener -> playbackListener.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer.status().time(), PlaybackStatus.FINISHED)))));
SwingUtilities.invokeLater(() -> this.listeners
.forEach(playbackListener -> playbackListener
.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, mediaPlayer
.status().time(), PlaybackStatus.FINISHED)))));
}
/**
@@ -386,7 +429,9 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
@Override
public void timeChanged(MediaPlayer mediaPlayer, long newTime)
{
SwingUtilities.invokeLater(() -> this.listeners.forEach(playbackListener -> playbackListener.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, newTime / 1000F, PlaybackStatus.PLAYING)))));
SwingUtilities.invokeLater(() -> this.listeners
.forEach(playbackListener -> playbackListener
.onPlaybackChanged(new PlaybackEvent(this, new PlaybackInfo(this.currentSong, newTime / 1000F, PlaybackStatus.PLAYING)))));
}
/**
@@ -531,7 +576,8 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
* other application) starts/stops playing media.
*
* @param mediaPlayer media player that raised the event
* @param corked <code>true</code> if corked; otherwise <code>false</code>
* @param corked <code>true</code> if corked; otherwise
* <code>false</code>
*/
@Override
public void corked(MediaPlayer mediaPlayer, boolean corked)
@@ -543,7 +589,8 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
* The audio was muted/un-muted.
*
* @param mediaPlayer media player that raised the event
* @param muted <code>true</code> if muted; otherwise <code>false</code>
* @param muted <code>true</code> if muted; otherwise
* <code>false</code>
*/
@Override
public void muted(MediaPlayer mediaPlayer, boolean muted)
@@ -609,9 +656,10 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
* The event will be fired again if the media is played again after a native
* stopped or finished event is received.
* <p>
* Waiting for this event may be more reliable than using {@link #playing(MediaPlayer)}
* or {@link #videoOutput(MediaPlayer, int)} in some cases (logo and marquee
* already mentioned, also setting audio tracks, sub-title tracks and so on).
* Waiting for this event may be more reliable than using {@link
* #playing(MediaPlayer)} or {@link #videoOutput(MediaPlayer, int)} in some
* cases (logo and marquee already mentioned, also setting audio tracks,
* sub-title tracks and so on).
*
* @param mediaPlayer media player that raised the event
*/
@@ -692,27 +740,40 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
private static class NullFuture<T> implements QueryFuture<T>
{
private final T value;
private final CommandConfirmation confirmation;
NullFuture()
{
this(null);
this((T) null);
}
NullFuture(T returnVal)
{
this.value = returnVal;
this.confirmation = new CommandConfirmation();
}
NullFuture(Throwable error)
{
this(error, null);
}
NullFuture(Throwable error, T returnVal)
{
this.value = returnVal;
this.confirmation = new CommandConfirmation(error);
}
@Override
public CommandConfirmation getConfirmation() throws CancellationException
{
return new CommandConfirmation();
return this.confirmation;
}
@Override
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit)
{
return new CommandConfirmation();
return this.getConfirmation();
}
@Override
@@ -742,7 +803,7 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return this.value;
return get();
}
}

View File

@@ -2,8 +2,10 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer;
package edu.regis.universeplayer.player;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
import edu.regis.universeplayer.browserCommands.QueryFuture;
import edu.regis.universeplayer.data.Song;
@@ -19,31 +21,6 @@ import java.util.HashMap;
*/
public interface Player<T extends Song>
{
HashMap<Class<? extends Song>, Player<?>> REGISTERED_PLAYERS = new HashMap<>();
/**
* Obtains a song player that can play the provided song.
*
* @param song - The song to play.
* @return A compatible player, or null if none is found.
*/
static Player<?> getCompatiblePlayer(Song song)
{
Player<?> player = REGISTERED_PLAYERS.get(song.getClass());
if (player == null)
{
for (Class<? extends Song> songClass : REGISTERED_PLAYERS.keySet())
{
if (songClass.isAssignableFrom(song.getClass()))
{
player = REGISTERED_PLAYERS.get(songClass);
break;
}
}
}
return player;
}
/**
* Obtains the song currently playing.
*

View File

@@ -0,0 +1,380 @@
package edu.regis.universeplayer.player;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.swing.JOptionPane;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
import edu.regis.universeplayer.browserCommands.CommandConfirmation;
import edu.regis.universeplayer.browserCommands.QueryFuture;
import edu.regis.universeplayer.data.InternetSong;
import edu.regis.universeplayer.data.LocalSong;
import edu.regis.universeplayer.data.PlaybackEvent;
import edu.regis.universeplayer.data.Queue;
import edu.regis.universeplayer.data.Song;
import edu.regis.universeplayer.gui.Interface;
/**
* The PlayerManager serves as the central access point for playing songs of any
* type.
*
* @author William Hubbard
* @version 0.1
*/
public class PlayerManager implements PlaybackListener
{
private static final Logger logger =
LoggerFactory.getLogger(PlayerManager.class);
private static PlayerManager INSTANCE;
private LinkedList<PlaybackListener> listeners = new LinkedList<>();
public static PlayerManager getPlayers()
{
if (INSTANCE == null)
{
INSTANCE = new PlayerManager();
}
return INSTANCE;
}
/**
* Links to other players.
*/
private final HashMap<Class<? extends Song>, Player> players =
new HashMap<>();
/**
* A reference to the player currently playing a song.
*/
private Player currentPlayer;
/**
* A reference to the song currently being played.
*/
private Song currentSong;
public PlayerManager()
{
this.initPlayers();
}
/**
* Obtains a song player that can play the provided song.
*
* @param song - The song to play.
* @return A compatible player, or null if none is found.
*/
public Player<?> getCompatiblePlayer(Song song)
{
Player<?> player = this.players.get(song.getClass());
if (player == null)
{
for (Class<? extends Song> songClass : this.players.keySet())
{
if (songClass.isAssignableFrom(song.getClass()))
{
player = this.players.get(songClass);
break;
}
}
}
return player;
}
/**
* Initializes the default players.
*/
private void initPlayers()
{
this.initPlayer(LocalSong.class, new LocalPlayer());
this.initPlayer(InternetSong.class, new BrowserPlayer());
}
private <T extends Song> void initPlayer(Class<T> songType,
Player<T> player)
{
boolean playerRegistered = this.players.containsValue(player);
this.players.put(songType, player);
if (!playerRegistered)
{
player.addPlaybackListener(this);
}
}
/**
* Performs the necessary shutdown procedures for all players.
*/
public void shutdownPlayers()
{
this.players.values().forEach(Player::close);
}
/**
* Obtains the active song player.
*
* @return - The player currently playing a song.
*/
protected Player getCurrentPlayer()
{
return this.currentPlayer;
}
/**
* Obtains the active song.
*
* @return - The song currently playing.
*/
public Song getCurrentSong()
{
return this.currentSong;
}
/**
* Creates a QueryFuture response for if no player is found.
*
* @param message - The message to send.
* @return A new future to return.
*/
private <T> QueryFuture<T> getNullPlayer(String message, T returnValue)
{
return new QueryFuture<T>()
{
@Override
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
{
if (returnValue instanceof Throwable)
{
return new CommandConfirmation((Throwable) returnValue);
}
else
{
return new CommandConfirmation(message);
}
}
@Override
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return this.getConfirmation();
}
@Override
public boolean cancel(boolean mayInterruptIfRunning)
{
return false;
}
@Override
public boolean isCancelled()
{
return false;
}
@Override
public boolean isDone()
{
return true;
}
@Override
public T get() throws InterruptedException, ExecutionException
{
return returnValue;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return this.get();
}
};
}
/**
* Creates a QueryFuture response for if no player is found.
*
* @param message - The error to send.
* @return A new future to return.
*/
private <T> QueryFuture<T> getNullPlayer(Throwable message, T returnValue)
{
return new QueryFuture<T>()
{
@Override
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
{
return new CommandConfirmation(message);
}
@Override
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return this.getConfirmation();
}
@Override
public boolean cancel(boolean mayInterruptIfRunning)
{
return false;
}
@Override
public boolean isCancelled()
{
return false;
}
@Override
public boolean isDone()
{
return true;
}
@Override
public T get() throws InterruptedException, ExecutionException
{
return returnValue;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return this.get();
}
};
}
public QueryFuture<Void> playSong(Song song)
{
if (this.currentSong != null)
{
this.currentPlayer.stopSong();
}
this.currentSong = null;
this.currentPlayer = this.getCompatiblePlayer(song);
if (this.currentPlayer == null)
{
throw new IllegalArgumentException("Unknown song type " + song
.getClass());
}
this.currentSong = song;
return this.currentPlayer.loadSong(song);
}
public QueryFuture<PlaybackStatus> getStatus()
{
if (this.currentPlayer != null)
{
return this.currentPlayer.getStatus();
}
return this.getNullPlayer("Command successful", PlaybackStatus.EMPTY);
}
public QueryFuture<Void> seek(float time)
{
if (this.currentPlayer != null)
{
return this.currentPlayer.seek(time);
}
return null;
}
public QueryFuture<Void> play()
{
if (this.currentPlayer != null && this.currentSong != null)
{
return this.currentPlayer.play();
}
return null;
}
public QueryFuture<Void> pause()
{
if (this.currentPlayer != null && this.currentSong != null)
{
return this.currentPlayer.pause();
}
return null;
}
public QueryFuture<Void> toggle()
{
if (this.currentPlayer != null && this.currentSong != null)
{
return this.currentPlayer.togglePlayback();
}
return null;
}
public QueryFuture<Void> stopSong()
{
if (this.currentPlayer != null && this.currentSong != null)
{
this.currentSong = null;
return this.currentPlayer.stopSong();
}
return null;
}
public void addPlaybackListener(PlaybackListener listener)
{
if (!this.hasPlaybackListener(listener))
{
this.listeners.add(listener);
}
}
public boolean hasPlaybackListener(PlaybackListener listener)
{
return this.listeners.contains(listener);
}
public void removePlaybackListener(PlaybackListener listener)
{
this.listeners.remove(listener);
}
/**
* Called when playback is changed.
*
* @param status - The playback status.
*/
@Override
public void onPlaybackChanged(PlaybackEvent status)
{
if (status.getSource() == this.currentPlayer)
{
for (PlaybackListener l : this.listeners)
{
l.onPlaybackChanged(status);
}
}
}
/**
* Sends an error to the browser player.
* @param forward - Whether the error should be thrown in a foreground
* script or a background script.
* @return The command future.
*/
public QueryFuture<Void> throwError(boolean forward)
{
BrowserPlayer player =
(BrowserPlayer) this.players.get(InternetSong.class);
if (player == null)
{
return this.getNullPlayer(new NullPointerException(
"No browser found"), null);
}
return player.throwError(forward);
}
}

View File

@@ -2,7 +2,8 @@
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
import edu.regis.universeplayer.player.Interface;
import edu.regis.universeplayer.ConfigManager;
import org.junit.Test;
import java.io.File;
@@ -13,53 +14,4 @@ import static junit.framework.Assert.assertTrue;
public class DBTest
{
@Test
public void test() throws ClassNotFoundException, SQLException
{
try
{
Class.forName("org.sqlite.JDBC");
Connection db;
Statement stat;
ResultSet tableResult;
// db = DriverManager.getConnection("jdbc:sqlite:" + new File(Interface.getDataDir().getAbsolutePath(), "universalmusictest.db").getAbsolutePath());
// db.setAutoCommit(false);
// stat = db.createStatement();
// tableResult = stat.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='INFO';");
// if (!tableResult.next())
// {
// System.out.println("Creating song table");
// /*
// * Create the table
// */
// stat.executeUpdate("CREATE TABLE INFO" +
// "(DATA INTEGER PRIMARY KEY NOT NULL);");
// }
// else
// {
// System.out.println("Clearing table");
// stat.executeUpdate("DELETE FROM INFO;");
// }
// tableResult.close();
// stat.executeUpdate("INSERT INTO INFO (DATA) VALUES (1);");
// stat.close();
// db.commit();
// db.close();
db = DriverManager.getConnection("jdbc:sqlite:" + new File(Interface.getDataDir().getAbsolutePath(), "universalmusictest.db").getAbsolutePath());
db.setAutoCommit(false);
stat = db.createStatement();
tableResult = stat.executeQuery("SELECT (DATA) FROM INFO");
assertTrue(tableResult.next());
assertEquals(1, tableResult.getInt("DATA"));
tableResult.close();
stat.close();
db.close();
}
catch (SQLException e)
{
e.printStackTrace();
throw e;
}
}
}