diff --git a/README.md b/README.md index 28c280c..dcc865a 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,13 @@ The effect has two different ways to set the colors, **album art** and **color p To add a color to the palette, use the color selection dropdown, and then press the _Add Color_ button to add it to the list. To remove a color from the palette, select the color in the list, then press the remove button. Finally, press the save button to apply your changes and update the colors. To go back to album art mode, open the settings drop down and enable it again. When you exit the program, both your color palette and color made will be saved for next time. +##### Switching the Effect +
+ +
+ +To change the effect, open the setting drop down, and move your mouse over the 'Choose Effect' option and another menu, with the [available effects](#available-effects) should appear. Your current effect will appear above the 'Now Playing' label in the playback view. + ## Troubleshooting @@ -87,22 +94,14 @@ To add a color to the palette, use the color selection dropdown, and then press * It can take a moment for the program to notice the song has changed, but once you see it change on the program, it should be reflected on the device. * If it still doesn't respond, in the settings menu there is a _reload effect_ button. Press that to restart the effect. If it doesn't work, I recommend restarting the program. - +## Available Effects: +- Pulse Beat: The classic and original effect. Creates a ripple that pulses out from a random panel on every beat. +- Fireworks: Lights up a random group of panels on every beat, like distant fireworks. +- Vibe: More minimal and bright, on every beat the color of a random panel gets brighter, and every bar the color changes. ## Future Goals -For future releases, here is my list of some of my goals ordered by priority: - -#### v1.0: -- [X] Refactoring and Improving Performance -- [X] Redo of the Color Palette UI -- [X] UI Overhaul - -#### v1.5: -- [ ] Adding Java Documentation to Source Code -- [ ] Adding a Firework Effect -- [ ] Adding Player Controls to UI - +All of my future goals for releases are in the project section of this repository, and you can keep track of the progress of them. If you have any suggestions for features, you can open an issue and I'll look into it. ## Credits diff --git a/assets/step4.png b/assets/step4.png new file mode 100644 index 0000000..35b32d8 Binary files /dev/null and b/assets/step4.png differ diff --git a/src/main/java/dev/jaxcksn/nanoleafMusic/DataManager.java b/src/main/java/dev/jaxcksn/nanoleafMusic/DataManager.java index 8207c4d..db377ec 100644 --- a/src/main/java/dev/jaxcksn/nanoleafMusic/DataManager.java +++ b/src/main/java/dev/jaxcksn/nanoleafMusic/DataManager.java @@ -5,6 +5,7 @@ package dev.jaxcksn.nanoleafMusic; +import ch.qos.logback.classic.Logger; import com.github.kevinsawicki.http.HttpRequest; import dev.jaxcksn.nanoleafMusic.effects.EffectType; import dev.jaxcksn.nanoleafMusic.utility.DataManagerException; @@ -12,6 +13,7 @@ import dev.jaxcksn.nanoleafMusic.utility.dMEC; import io.github.rowak.nanoleafapi.Aurora; import io.github.rowak.nanoleafapi.StatusCodeException; +import org.slf4j.LoggerFactory; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; @@ -25,9 +27,11 @@ public class DataManager { private static final Preferences preferences = Preferences.userNodeForPackage(Main.class); public boolean hasSaved; + private static final Logger logger + = (Logger) LoggerFactory.getLogger("nanoleafMusic.DataManager"); public DataManager() { - String testForSaved = preferences.get("savedDevice",null); + String testForSaved = preferences.get("savedDevice", null); hasSaved = testForSaved != null && !testForSaved.isEmpty(); } @@ -39,6 +43,7 @@ public void saveDevice(Aurora device) { ";" + device.getAccessToken(); preferences.put("savedDevice", str); + logger.info("Saved {} to preferences", device.getName()); try { preferences.flush(); } catch (BackingStoreException e) { @@ -49,6 +54,7 @@ public void saveDevice(Aurora device) { public Aurora loadDevice() { String saved = preferences.get("savedDevice",null); if (saved == null || saved.isEmpty() || !hasSaved) { + logger.error("Could not load from preferences, key is null or empty."); throw new DataManagerException("Could not load from preferences, key is null or empty.", dMEC.NDS); } else { try { @@ -57,12 +63,15 @@ public Aurora loadDevice() { int port = Integer.parseInt(deviceData[1]); String accessToken = deviceData[2]; try { + logger.info("Loading device at {} from preferences", hostName); return new Aurora(hostName,port,"v1",accessToken); } catch (StatusCodeException | HttpRequest.HttpRequestException e) { + logger.error("Error creating device object from saved data.", e); throw new DataManagerException("Error creating device object from saved data.",dMEC.ISD); } } catch (Exception e) { + logger.error("Could not process saved device data, string may be malformed.", e); throw new DataManagerException("Could not process saved device data, string may be malformed.", dMEC.MDS); } } @@ -70,17 +79,12 @@ public Aurora loadDevice() { public void removeDevice() { preferences.remove("savedDevice"); + logger.info("Removed saved device from preferences"); hasSaved = false; } public static Settings loadSettings() { - boolean albumColors = preferences.getBoolean("useAlbumColors",true); - int albumPaletteLength = preferences.getInt("numberOfAlbumColors",6); - if(albumPaletteLength > 12) { - albumPaletteLength = 12; - } else if (albumPaletteLength < 3) { - albumPaletteLength = 3; - } + boolean albumColors = preferences.getBoolean("useAlbumColors", true); String colorPalette = preferences.get("colorPalette", "#FF0000,#00FF00,#0000FF"); if (colorPalette.length() > 95) { colorPalette = colorPalette.substring(0, 95); @@ -89,27 +93,33 @@ public static Settings loadSettings() { } String effectString = preferences.get("selectedEffect", "PULSEBEAT"); EffectType activeEffectType = EffectType.valueOf(effectString); - return new Settings(albumColors, albumPaletteLength, colorPalette, activeEffectType); + logger.info("Loaded settings from preferences"); + return new Settings(albumColors, colorPalette, activeEffectType); } public static void updateSettings(Settings settings) { preferences.putBoolean("useAlbumColors", settings.albumColors); preferences.put("colorPalette", settings.colorPalette); + preferences.put("savedEffect", settings.activeEffectType.toString()); + logger.info("Updated settings in preferences"); } public static void changeAlbumMode(boolean b) { preferences.putBoolean("useAlbumColors", b); + logger.info("Changed album mode to {} in preferences", b); } public static void changeEffectType(EffectType effectType) { preferences.put("selectedEffect", effectType.toString()); + logger.info("Changed saved effect type to {} in preferences", effectType); } public static void clearSavedData() { try { preferences.clear(); + logger.info("Cleared all data from preferences"); } catch (BackingStoreException e) { - e.printStackTrace(); + Main.showException(e); } } diff --git a/src/main/java/dev/jaxcksn/nanoleafMusic/EffectManager.java b/src/main/java/dev/jaxcksn/nanoleafMusic/EffectManager.java index fb6ee29..c0194ee 100644 --- a/src/main/java/dev/jaxcksn/nanoleafMusic/EffectManager.java +++ b/src/main/java/dev/jaxcksn/nanoleafMusic/EffectManager.java @@ -5,6 +5,7 @@ package dev.jaxcksn.nanoleafMusic; +import ch.qos.logback.classic.Logger; import com.wrapper.spotify.SpotifyApi; import com.wrapper.spotify.exceptions.SpotifyWebApiException; import com.wrapper.spotify.model_objects.credentials.AuthorizationCodeCredentials; @@ -18,10 +19,7 @@ import com.wrapper.spotify.requests.data.tracks.GetAudioAnalysisForTrackRequest; import de.androidpit.colorthief.ColorThief; import dev.jaxcksn.nanoleafMusic.controllers.PlaybackView; -import dev.jaxcksn.nanoleafMusic.effects.EffectType; -import dev.jaxcksn.nanoleafMusic.effects.FireworkEffect; -import dev.jaxcksn.nanoleafMusic.effects.MusicEffect; -import dev.jaxcksn.nanoleafMusic.effects.PulseBeatEffect; +import dev.jaxcksn.nanoleafMusic.effects.*; import dev.jaxcksn.nanoleafMusic.utility.PaletteColor; import dev.jaxcksn.nanoleafMusic.utility.Settings; import dev.jaxcksn.nanoleafMusic.utility.SpecificAudioAnalysis; @@ -34,6 +32,7 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; import org.apache.hc.core5.http.ParseException; +import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -41,7 +40,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.net.URL; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -64,13 +62,14 @@ public class EffectManager { public Settings settings; public Color[] palette = new Color[]{Color.RED, Color.BLUE, Color.GREEN}; private ScheduledExecutorService sES; + private static final Logger logger + = (Logger) LoggerFactory.getLogger("nanoleafMusic.EffectManager"); public EffectManager(SpotifyApi spotifyApi, int expiresIn, Aurora device, PlaybackView viewController) { this.spotifyApi = spotifyApi; this.expiresIn = expiresIn; this.device = device; this.viewController = viewController; - settings = DataManager.loadSettings(); switch (settings.activeEffectType) { case FIREWORKS: @@ -79,14 +78,16 @@ public EffectManager(SpotifyApi spotifyApi, int expiresIn, Aurora device, Playba case PULSEBEAT: this.activeEffect = new PulseBeatEffect(palette, device); break; + case VIBE: + this.activeEffect = new VibeEffect(palette, device); + break; } - System.out.println("\u001b[92;1m✔\u001b[0m Effect Manager Loaded"); + logger.info("Effect manager object initialized, starting refresh timer"); startRefreshTimer(); } public void switchEffect(EffectType effectType) { - System.out.println("\u001b[96;1mℹ\u001b[0m Changing Effect"); settings.activeEffectType = effectType; Color[] currentPalette = activeEffect.getPalette(); switch (effectType) { @@ -96,16 +97,20 @@ public void switchEffect(EffectType effectType) { case PULSEBEAT: this.activeEffect = new PulseBeatEffect(currentPalette, device); break; + case VIBE: + this.activeEffect = new VibeEffect(currentPalette, device); + break; } } public void reloadEffect() { - System.out.println("\n" + "\u001b[96;1mℹ\u001b[0m Attempting to Restart Effect"); + logger.info("Reloading Effect..."); + logger.warn("Attempting to shut down the Scheduled Executor Service. If this fails, the program can't recover."); sES.shutdownNow(); try { - if (!sES.awaitTermination(30, TimeUnit.SECONDS)) { - System.err.println("Pool did not terminate"); + if (!sES.awaitTermination(60, TimeUnit.SECONDS)) { + throw new Exception("Scheduled Executor Service failed to shutdown"); } else { isPlaying = false; isRunning = false; @@ -115,10 +120,11 @@ public void reloadEffect() { activeEffect.setPalette(palette); } this.startEffect(); - System.out.println("\u001b[92;1m✔\u001b[0m Finished Restarting Effect\n"); + logger.info("Finished reloading the effect"); } - } catch (InterruptedException e) { - e.printStackTrace(); + } catch (Exception e) { + Main.showException(e); + System.exit(1); } @@ -135,7 +141,7 @@ private void startRefreshTimer() { spotifyApi.setRefreshToken(authorizationCodeCredentials.getRefreshToken()); expiresIn = authorizationCodeCredentials.getExpiresIn(); } catch (ParseException | IOException e) { - e.printStackTrace(); + Main.showException(e); } catch (SpotifyWebApiException spotifyWebApiException) { showSWAE(spotifyWebApiException); } @@ -151,15 +157,15 @@ public void startEffect() { if (!settings.albumColors) { palette = PaletteColor.toEffectColorArray(settings.colorPalette); } - - sES = Executors.newScheduledThreadPool(4 * Runtime.getRuntime().availableProcessors()); - System.out.println("\u001b[96;1mℹ\u001b[0m Using " + 4 * Runtime.getRuntime().availableProcessors() + " threads."); + int availableProcessors = Runtime.getRuntime().availableProcessors(); + sES = Executors.newScheduledThreadPool(4 * availableProcessors, new Main.NamedThreadFactory("effect")); + logger.info("There are {} cores available, using a thread pool of {} threads", availableProcessors, 4 * availableProcessors); Runnable effectPulseTask = () -> { if (isPlaying) { try { pulseTask(); } catch (StatusCodeException | IOException e) { - e.printStackTrace(); + Main.showException(e); } } }; @@ -168,7 +174,7 @@ public void startEffect() { try { spotifyTask(); } catch (ParseException | IOException | InterruptedException e) { - e.printStackTrace(); + Main.showException(e); } catch (SpotifyWebApiException spotifyWebApiException) { showSWAE(spotifyWebApiException); } @@ -176,18 +182,18 @@ public void startEffect() { //Prevents UI From Freezing Up when Nothing is Playing Thread initThread = new Thread(this::initEffect); + initThread.setName("effect-init"); initThread.start(); - System.out.println("\u001b[92;1m✔\u001b[0m Starting Initialization"); try { initThread.join(); } catch (InterruptedException e) { - e.printStackTrace(); + Main.showException(e); } sES.scheduleAtFixedRate(effectPulseTask, 0, 100, TimeUnit.MILLISECONDS); - System.out.println("\u001b[92;1m✔\u001b[0m Pulse Timers Started"); + logger.info("Effect timer was scheduled"); sES.scheduleAtFixedRate(spotifyUpdateTask, 0, 2000, TimeUnit.MILLISECONDS); - System.out.println("\u001b[92;1m✔\u001b[0m Spotify Update Timers Started"); + logger.info("Spotify Poll timer was scheduled"); displayTrackInformation(true, false); } } @@ -196,7 +202,7 @@ private void initEffect() { try { CurrentlyPlaying currentlyPlaying = getCurrentlyPlaying(); if (currentlyPlaying == null) { - System.out.println("\u001b[96;1mℹ\u001b[0m Current Playback returned null, starting wait loop."); + logger.warn("Nothing is playing on Spotify, polling again in 5 seconds."); } while (currentlyPlaying == null && !isPlaying) { TimeUnit.SECONDS.sleep(5); @@ -207,9 +213,9 @@ private void initEffect() { currentTrackAnalysis = getTrackAnalysis(currentTrack.getId()); progress = currentlyPlaying.getProgress_ms(); isPlaying = true; - System.out.println("\u001b[92;1m✔\u001b[0m Finished initialization"); + logger.info("Finished effect initialization"); } catch (ParseException | IOException | InterruptedException e) { - e.printStackTrace(); + Main.showException(e); } catch (SpotifyWebApiException spotifyWebApiException) { showSWAE(spotifyWebApiException); } @@ -261,49 +267,34 @@ private void pulseTask() throws StatusCodeException, IOException { private void spotifyTask() throws ParseException, SpotifyWebApiException, IOException, InterruptedException { CurrentlyPlaying currentPlayback = getCurrentlyPlaying(); if (currentPlayback == null) { + if (isPlaying) { + logger.warn("Nothing is playing on Spotify. "); + } isPlaying = false; - CountDownLatch playLatch = new CountDownLatch(1); - displayTrackInformation(false, false); - new Thread(() -> { - try { - CurrentlyPlaying current = getCurrentlyPlaying(); - while (current == null) { - TimeUnit.SECONDS.sleep(4); - current = getCurrentlyPlaying(); - } - playLatch.countDown(); - } catch (ParseException | IOException | InterruptedException e) { - e.printStackTrace(); - } catch (SpotifyWebApiException spotifyWebApiException) { - showSWAE(spotifyWebApiException); - } - }).start(); - playLatch.await(); - currentPlayback = getCurrentlyPlaying(); - } + viewController.setPlayback(false); + } else { + Track newTrack = ((Track) currentPlayback.getItem()); + if (!currentTrack.getId().equals(newTrack.getId())) { + currentTrack = newTrack; + currentTrackAnalysis = getTrackAnalysis(newTrack.getId()); + progress = currentPlayback.getProgress_ms(); + displayTrackInformation(true, false); + } - Track newTrack = ((Track) currentPlayback.getItem()); - if(!currentTrack.getId().equals(newTrack.getId())) { - currentTrack = newTrack; - currentTrackAnalysis = getTrackAnalysis(newTrack.getId()); - progress = currentPlayback.getProgress_ms(); - displayTrackInformation(true, false); - } + float progressDifference = Math.abs(currentPlayback.getProgress_ms() - progress); + if (currentPlayback.getIs_playing() && !isPlaying) { + isPlaying = true; - float progressDifference = Math.abs(currentPlayback.getProgress_ms() - progress); - if(currentPlayback.getIs_playing() && !isPlaying) { - isPlaying = true; - progress = currentPlayback.getProgress_ms() + 500; - displayTrackInformation(true, false); - } else if(!currentPlayback.getIs_playing() && isPlaying) { - isPlaying = false; - progress = currentPlayback.getProgress_ms(); - displayTrackInformation(true, true); - } else if (currentPlayback.getIs_playing() && progressDifference >= 10) { - progress = currentPlayback.getProgress_ms(); + progress = currentPlayback.getProgress_ms() + 500; + displayTrackInformation(true, false); + } else if (!currentPlayback.getIs_playing() && isPlaying) { + isPlaying = false; + progress = currentPlayback.getProgress_ms(); + displayTrackInformation(true, true); + } else if (currentPlayback.getIs_playing() && progressDifference >= 10) { + progress = currentPlayback.getProgress_ms(); + } } - - } public void displayTrackInformation(boolean updateArt, boolean isPaused) { @@ -335,7 +326,7 @@ public void displayTrackInformation(boolean updateArt, boolean isPaused) { int[][] colorArray = ColorThief.getPalette(image, 6); activeEffect.setPalette(colorArray); } catch (IOException e) { - e.printStackTrace(); + Main.showException(e); } viewController.setPlayback(currentTrack.getName(), songArtists, artworkURL); }).start(); diff --git a/src/main/java/dev/jaxcksn/nanoleafMusic/Main.java b/src/main/java/dev/jaxcksn/nanoleafMusic/Main.java index 5566950..09dc039 100644 --- a/src/main/java/dev/jaxcksn/nanoleafMusic/Main.java +++ b/src/main/java/dev/jaxcksn/nanoleafMusic/Main.java @@ -6,35 +6,52 @@ package dev.jaxcksn.nanoleafMusic; import ca.weblite.objc.Proxy; -import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import dev.jaxcksn.nanoleafMusic.utility.NSProcessInfoUtils; import javafx.application.Application; +import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; import javafx.scene.text.Font; import javafx.stage.Stage; import org.slf4j.LoggerFactory; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Locale; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; public class Main extends Application { private static Proxy appNapPrevented; + private static final Logger logger + = (Logger) LoggerFactory.getLogger("nanoleafMusic.Main"); public static void main(String[] args) { - Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.setLevel(Level.INFO); + logger.info("Application Started"); if (isMac()) { + logger.info("macOS detected, attempting to prevent App Nap"); appNapPrevented = NSProcessInfoUtils.beginActivityWithOptions("Needs to be alive to constantly update effect."); } - System.out.println("\u001b[92;1m✔\u001b[0m Starting Application"); + + Thread.UncaughtExceptionHandler handler = ((th, ex) -> { + showException(new Exception(ex)); + }); + Thread.setDefaultUncaughtExceptionHandler(handler); + launch(args); } @Override public void start(Stage stage) throws Exception { + Thread.currentThread().setName("app"); Parent root = FXMLLoader.load(getClass().getResource("/connectToDevice.fxml")); Scene scene = new Scene(root, 400, 300); @@ -44,10 +61,28 @@ public void start(Stage stage) throws Exception { Font.loadFont(getClass().getResourceAsStream("/fonts/OpenSans-ExtraBold.ttf"), 12); Font.loadFont(getClass().getResourceAsStream("/fonts/HankRnd-Black.ttf"), 12); root.getStylesheets().add("/gui.css"); + logger.info("JavaFX Assets Loaded"); stage.setTitle("nanoleafMusic"); stage.setResizable(false); stage.setScene(scene); + logger.info("Setting JavaFX scene to 'ConnectToDevice' view"); stage.show(); + + } + + public static class NamedThreadFactory implements ThreadFactory { + String name; + AtomicInteger threadNo = new AtomicInteger(0); + + public NamedThreadFactory(String name) { + this.name = name; + } + + @Override + public Thread newThread(Runnable r) { + String threadName = name + "-" + threadNo.incrementAndGet(); + return new Thread(r, threadName); + } } @Override @@ -62,4 +97,42 @@ public static boolean isMac() { String OS = System.getProperty("os.name", "unknown").toLowerCase(Locale.ROOT); return OS.contains("mac"); } + + public static void showException(Exception e) { + logger.error("An Exception was Thrown", e); + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Exception"); + alert.setHeaderText("Program Exception Thrown"); + alert.setContentText("An exception or error was thrown while running the program. The program might not run after this happens."); + + // Create expandable Exception. + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + String exceptionText = sw.toString(); + + Label label = new Label("The exception stacktrace was:"); + + TextArea textArea = new TextArea(exceptionText); + textArea.setEditable(false); + textArea.setWrapText(true); + + textArea.setMaxWidth(Double.MAX_VALUE); + textArea.setMaxHeight(Double.MAX_VALUE); + GridPane.setVgrow(textArea, Priority.ALWAYS); + GridPane.setHgrow(textArea, Priority.ALWAYS); + + GridPane expContent = new GridPane(); + expContent.setMaxWidth(Double.MAX_VALUE); + expContent.add(label, 0, 0); + expContent.add(textArea, 0, 1); + +// Set expandable Exception into the dialog pane. + alert.getDialogPane().setExpandableContent(expContent); + alert.getDialogPane().getStylesheets().add("/gui.css"); + alert.showAndWait(); + }); + } } + diff --git a/src/main/java/dev/jaxcksn/nanoleafMusic/SpotifyManager.java b/src/main/java/dev/jaxcksn/nanoleafMusic/SpotifyManager.java index 4e29ecf..d531170 100644 --- a/src/main/java/dev/jaxcksn/nanoleafMusic/SpotifyManager.java +++ b/src/main/java/dev/jaxcksn/nanoleafMusic/SpotifyManager.java @@ -5,6 +5,7 @@ package dev.jaxcksn.nanoleafMusic; +import ch.qos.logback.classic.Logger; import com.wrapper.spotify.SpotifyApi; import com.wrapper.spotify.SpotifyHttpManager; import com.wrapper.spotify.exceptions.SpotifyWebApiException; @@ -19,6 +20,7 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; import org.apache.hc.core5.http.ParseException; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.PrintWriter; @@ -36,7 +38,8 @@ public class SpotifyManager { .setRedirectUri(REDIRECT_URI) .build(); public CallbackServer cbServer; - + private static final Logger logger + = (Logger) LoggerFactory.getLogger("nanoleafMusic.SpotifyManager"); public URI connectURI; public int expiresIn; @@ -45,7 +48,7 @@ public SpotifyManager() { try { pkceVerification = PKCE.generateCodeVerifier(); } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + Main.showException(e); } AuthorizationCodeUriRequest authorizationCodeUriRequest = null; @@ -54,12 +57,12 @@ public SpotifyManager() { .scope("user-read-currently-playing, user-read-playback-state") .build(); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + Main.showException(e); } assert authorizationCodeUriRequest != null; connectURI = authorizationCodeUriRequest.execute(); cbServer = new CallbackServer(); - System.out.println("\u001b[92;1m✔\u001b[0m Started Callback Server"); + logger.info("Callback server started and listening at localhost:8001/connect"); } public void getCredentials(String accessCode) { @@ -71,7 +74,7 @@ public void getCredentials(String accessCode) { spotifyApi.setRefreshToken(authorizationCodeCredentials.getRefreshToken()); expiresIn = authorizationCodeCredentials.getExpiresIn(); } catch (ParseException | IOException e) { - e.printStackTrace(); + Main.showException(e); } catch (SpotifyWebApiException spotifyWebApiException) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Exception"); diff --git a/src/main/java/dev/jaxcksn/nanoleafMusic/controllers/ConnectToDevice.java b/src/main/java/dev/jaxcksn/nanoleafMusic/controllers/ConnectToDevice.java index 98b89af..d8d3634 100644 --- a/src/main/java/dev/jaxcksn/nanoleafMusic/controllers/ConnectToDevice.java +++ b/src/main/java/dev/jaxcksn/nanoleafMusic/controllers/ConnectToDevice.java @@ -5,6 +5,7 @@ package dev.jaxcksn.nanoleafMusic.controllers; +import ch.qos.logback.classic.Logger; import dev.jaxcksn.nanoleafMusic.DataManager; import dev.jaxcksn.nanoleafMusic.Main; import dev.jaxcksn.nanoleafMusic.utility.DataManagerException; @@ -29,6 +30,7 @@ import net.straylightlabs.hola.sd.Instance; import net.straylightlabs.hola.sd.Query; import net.straylightlabs.hola.sd.Service; +import org.slf4j.LoggerFactory; import java.awt.*; import java.io.IOException; @@ -51,10 +53,12 @@ public class ConnectToDevice { private ObservableList