Complete assignment #1
@@ -3,6 +3,7 @@ package sbu.javafx;
|
|||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class MusicApp extends Application {
|
public class MusicApp extends Application {
|
||||||
@@ -13,6 +14,7 @@ public class MusicApp extends Application {
|
|||||||
getClass().getResource("App-view.fxml"));
|
getClass().getResource("App-view.fxml"));
|
||||||
Scene scene = new Scene(loader.load());
|
Scene scene = new Scene(loader.load());
|
||||||
stage.setTitle("Music Player");
|
stage.setTitle("Music Player");
|
||||||
|
stage.getIcons().add(new Image("/sbu/images/default-cover.png"));
|
||||||
stage.setScene(scene);
|
stage.setScene(scene);
|
||||||
stage.setResizable(false);
|
stage.setResizable(false);
|
||||||
stage.show();
|
stage.show();
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ public class MusicController {
|
|||||||
private boolean isShuffle = false;
|
private boolean isShuffle = false;
|
||||||
private boolean isRepeat = false;
|
private boolean isRepeat = false;
|
||||||
|
|
||||||
|
// theme button
|
||||||
|
@FXML private Button themeBtn;
|
||||||
|
private boolean isDarkMode = false;
|
||||||
|
|
||||||
// ========================================= Methods ============================================
|
// ========================================= Methods ============================================
|
||||||
public void initialize(){ // runs without calling
|
public void initialize(){ // runs without calling
|
||||||
libraryView.setItems(library);
|
libraryView.setItems(library);
|
||||||
@@ -461,4 +465,18 @@ public class MusicController {
|
|||||||
libraryTabBtn.getStyleClass().remove("tab-active");
|
libraryTabBtn.getStyleClass().remove("tab-active");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// theme controller
|
||||||
|
@FXML
|
||||||
|
public void handleThemeToggle() {
|
||||||
|
isDarkMode = !isDarkMode;
|
||||||
|
javafx.scene.Scene scene = themeBtn.getScene();
|
||||||
|
|
||||||
|
if (isDarkMode) {
|
||||||
|
scene.getRoot().getStyleClass().add("dark");
|
||||||
|
themeBtn.setText("☀️");
|
||||||
|
} else {
|
||||||
|
scene.getRoot().getStyleClass().remove("dark");
|
||||||
|
themeBtn.setText("🌙");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,12 @@
|
|||||||
spacing="20"
|
spacing="20"
|
||||||
prefWidth="320">
|
prefWidth="320">
|
||||||
|
|
||||||
|
<!-- Dark Mode Toggle -->
|
||||||
|
<HBox alignment="TOP_RIGHT" fillHeight="false">
|
||||||
|
<Button fx:id="themeBtn" text="🌙" styleClass="theme-btn"
|
||||||
|
onAction="#handleThemeToggle"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="32" right="28" bottom="32" left="28"/>
|
<Insets top="32" right="28" bottom="32" left="28"/>
|
||||||
</padding>
|
</padding>
|
||||||
|
|||||||
@@ -124,13 +124,6 @@
|
|||||||
-fx-background-color: #FAFAFA;
|
-fx-background-color: #FAFAFA;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlist-header {
|
|
||||||
-fx-font-size: 14px;
|
|
||||||
-fx-font-weight: bold;
|
|
||||||
-fx-text-fill: #424242;
|
|
||||||
-fx-padding: 0 0 8 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== ListView ===== */
|
/* ===== ListView ===== */
|
||||||
.playlist {
|
.playlist {
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
@@ -247,7 +240,144 @@
|
|||||||
-fx-text-fill: #212121;
|
-fx-text-fill: #212121;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== Album Cover rounded corners ===== */
|
/* ===== Theme Button ===== */
|
||||||
.cover-container {
|
.theme-btn {
|
||||||
-fx-background-radius: 12px;
|
-fx-background-color: transparent;
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
-fx-padding: 4 8 4 8;
|
||||||
|
-fx-background-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-btn:hover {
|
||||||
|
-fx-background-color: #F0F0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================= */
|
||||||
|
/* ===== Dark Mode ===== */
|
||||||
|
/* ========================================= */
|
||||||
|
|
||||||
|
.dark .root {
|
||||||
|
-fx-background-color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .player-panel {
|
||||||
|
-fx-background-color: #1E1E1E;
|
||||||
|
-fx-border-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .playlist-panel {
|
||||||
|
-fx-background-color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .cover-container {
|
||||||
|
-fx-background-color: #2A2A2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .song-title {
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .artist-name {
|
||||||
|
-fx-text-fill: #AAAAAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .time-label {
|
||||||
|
-fx-text-fill: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .progress-slider .track {
|
||||||
|
-fx-background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .progress-slider .thumb {
|
||||||
|
-fx-background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .volume-slider .track {
|
||||||
|
-fx-background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .volume-slider .thumb {
|
||||||
|
-fx-background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .play-btn {
|
||||||
|
-fx-background-color: #FFFFFF;
|
||||||
|
-fx-text-fill: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .play-btn:hover {
|
||||||
|
-fx-background-color: #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .control-btn {
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .control-btn:hover {
|
||||||
|
-fx-background-color: #2A2A2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .theme-btn:hover {
|
||||||
|
-fx-background-color: #2A2A2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tab-bar {
|
||||||
|
-fx-background-color: #1A1A1A;
|
||||||
|
-fx-border-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tab-btn {
|
||||||
|
-fx-text-fill: #9E9E9E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tab-active {
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
|
-fx-border-color: transparent transparent #FFFFFF transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tab-content {
|
||||||
|
-fx-background-color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tab-header {
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .playlist .list-cell {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-text-fill: #CCCCCC;
|
||||||
|
-fx-border-color: transparent transparent #222222 transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .playlist .list-cell:hover {
|
||||||
|
-fx-background-color: #1E1E1E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .playlist .list-cell:selected {
|
||||||
|
-fx-background-color: #2A2A2A;
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .playlist .scroll-bar:vertical .thumb {
|
||||||
|
-fx-background-color: #444444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .add-btn {
|
||||||
|
-fx-background-color: #FFFFFF;
|
||||||
|
-fx-text-fill: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .add-btn:hover {
|
||||||
|
-fx-background-color: #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .back-btn {
|
||||||
|
-fx-text-fill: #9E9E9E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .back-btn:hover {
|
||||||
|
-fx-background-color: #2A2A2A;
|
||||||
|
-fx-text-fill: #FFFFFF;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user