Rename year directories to allow natural ordering

This commit is contained in:
2023-12-20 03:57:27 +00:00
parent 0ab1f5ad3a
commit 1f7d812b98
1895 changed files with 0 additions and 7188 deletions

View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>assignment4</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,13 @@
1., "Personal Holloway", 3:23
2., "Greedy Fly", 4:30
3., "Swallowed", 4:51
4., "Insect Kin", 4:27
5., "Cold Contagious", 6:00
6., "A Tendency to Start Fires", 4:04
7., "Mouth", 5:45
8., "Straight No Chaser", 4:02
9., "History", 4:17
10., "Synapse", 4:52
11., "Communicator", 4:25
12., "Bonedriven", 4:32
13., "Distant Voices", 6:39

View File

@ -0,0 +1,11 @@
1., "Negative Vibes", 4:44
2., "Ghosts of Overdoses", 4:41
3., "It's All Good", 4:21
4., "Factories", 5:17
5., "Jar Song", 5:03
6., "Celtic Tiger", 5:13
7., "Apple of My Eye", 3:43
8., "Industrial School", 5:27
9., "Great Gaels of Ireland", 5:21
10., "Marching Season Siege", 3:24
11., "Seize the Day" (hidden track), 4:12

View File

@ -0,0 +1,11 @@
1., "Babooshka", 3:20
2., "Delius (Song of Summer)", 2:51
3., "Blow Away (For Bill)", 3:33
4., "All We Ever Look For", 3:47
5., "Egypt", 4:10
6., "The Wedding List", 4:15
7., "Violin", 3:15
8., "The Infant Kiss", 2:50
9., "Night Scented Stock", 0:51
10., "Army Dreamers", 2:55
11., "Breathing", 5:29

View File

@ -0,0 +1,10 @@
1, Nasty, 4:40
2, O.D., 3:22
3, Death Note, 3:40
4, Bad, 3:55
5, Drown, 3:54
6, Saucy, 3:04
7, Yas, 3:22
8, So Strange, 4:00
9, Rich Kids, 3:21
10, G.O.A.T., 3:35

View File

@ -0,0 +1,11 @@
1., "Here Comes the Sun", 3:05
2., "Because", 2:45
3., "You Never Give Me Your Money", 4:03
4., "Sun King", 2:26
5., "Mean Mr. Mustard", 1:06
6., "Polythene Pam", 1:13
7., "She Came In Through the Bathroom Window", 1:58
8., "Golden Slumbers", 1:31
9., "Carry That Weight", 1:36
10., "The End", 2:05
11., "Her Majesty", 0:23

View File

@ -0,0 +1,5 @@
Bush, Razorblade Suitcase, covers/Razorblade_suitcase.jpg, library/bush_razorblade_suitcase.txt
Kate Bush, Never for Ever, covers/Katebushneverforever.png, library/kate_bush_never_for_ever.txt
Damien Dempsey, Seize the Day, covers/Damien_Dempsey_-_Seize_the_Day.jpg, library/damien_dempsey_seize_the_day.txt
Beatles, Abbey Road, covers/Beatles_-_Abbey_Road.jpg, library/the_beatles_abbey_road.txt
Polyphia, New Levels New Devils, covers/polyphia_new_levels_new_devils.jpeg, library/new_levels_new_devils.txt

View File

@ -0,0 +1,120 @@
// Name: Andrew Hayes
// Student ID: 21321503
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* class to represent an Album object and its tracks
*/
public class Album {
private String artist; // the name of the artist
private String title; // the title of the album
private String pathToCover; // the path to the cover image of the album
private String pathToTrackList; // the path to the track list text file for the album
private ArrayList<Track> tracks = new ArrayList<>(); // arraylist of all the tracks on the album
/**
* constructor for Album objects
* @param artist String of the artist's name
* @param title String of the title of the album
* @param pathToCover String of the filepath to the cover image
* @param pathToTrackList String of the filepath to the list of tracks on the album
*/
public Album(String artist, String title, String pathToCover, String pathToTrackList) throws IOException {
this.artist = artist;
this.title = title;
this.pathToCover = pathToCover;
this.pathToTrackList = pathToTrackList;
// reading the trackList file and adding a Track object to the ArrayList for each line in the file
BufferedReader reader = new BufferedReader(new FileReader(pathToTrackList)); // not catching FileNotFoundException as entire method should fail if the trackList file is not accessible
String line;
while ((line = reader.readLine()) != null) {
String[] columns = line.split(",");
tracks.add(new Track(columns[0].strip(), columns[1].strip(), columns[2].strip())); // trimming whitespace from the ends of each column read in
}
}
/**
* getter for the artist's name
* @return String artist
*/
public String getArtist() {
return artist;
}
/**
* setter for the artist's name
* @param artist String of the artist's name
*/
public void setArtist(String artist) {
this.artist = artist;
}
/**
* getter for the title
* @return String title of the album
*/
public String getTitle() {
return title;
}
/**
* setter for the title
* @param title String title of the album
*/
public void setTitle(String title) {
this.title = title;
}
/**
* getter for pathToCover
* @return String path to the cover image
*/
public String getPathToCover() {
return pathToCover;
}
/**
* setter for pathToCover
* @param pathToCover String of the filepath to the cover image
*/
public void setPathToCover(String pathToCover) {
this.pathToCover = pathToCover;
}
/**
* getter for trackList
* @return String of the filepath to the trackList
*/
public String getPathToTrackList() {
return pathToTrackList;
}
/**
* setter for trackList
* @param pathToTrackList String of the filepath to the trackLists
*/
public void setPathToTrackList(String pathToTrackList) {
this.pathToTrackList = pathToTrackList;
}
/**
* getter for tracks
* @return Array of Track objects
*/
public ArrayList<Track> getTracks() {
return tracks;
}
/**
* setter for tracks
* @param tracks array of Track objects
*/
public void setTracks(ArrayList<Track> tracks) {
this.tracks = tracks;
}
}

View File

@ -0,0 +1,181 @@
// Name: Andrew Hayes
// Student ID: 21321503
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
/**
* Application class for the Music Library application
*/
public class MusicLibrary extends JFrame {
private String libraryDirectory = "resources/"; // directory that the library files are in
private String libraryFileName = "music_library.txt"; // name of the music libary file
private ArrayList<Album> albums = new ArrayList<>();
private ActionListener actionListener; // action listener for the buttons in this application
/**
* constructor for the Music Library application
*/
public MusicLibrary() {
super("Music Library"); // set window title
// make JFrame fill the screen
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setSize(screenSize.width, screenSize.height);
// using border layout to position JPanels easily
Container container = getContentPane();
container.setLayout(new BorderLayout());
// panel to show the list of albums
JPanel albumPanel = new JPanel();
// action listener to handle what happens when buttons are clicked
actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
// if the actionCommand was to show the albumPanel (i.e., "back" button was pressed on the trackPanel)
if (event.getActionCommand().equals("showAlbumPanel")) {
// removing everything from the container
container.removeAll();
// cleaning screen
container.revalidate();
container.repaint();
// adding albumPanel to container
container.add(albumPanel, BorderLayout.CENTER);
}
// else if the actionCommand was anything other than showAlbumPanel, i.e. it was an album being clicked, hide it and display the tracklist of the selected album
else {
// hiding the albumPanel
container.remove(albumPanel);
// cleaning screen
container.revalidate();
container.repaint();
// displaying album contents (trackPanel)
container.add(generateTrackPanel(albums.get(Integer.parseInt(event.getActionCommand()))), BorderLayout.CENTER);
}
}
};
// loading the albums into the arraylist
try {
albums = loadAlbums(libraryDirectory + libraryFileName);
}
// display error message if the music library file could not be read successfully
catch (IOException e) {
albumPanel.add(new JLabel("The music library file could not be read successfully!!!"));
}
// iterating over each album and adding it to the GUI interface as a button
for (int i = 0; i < albums.size(); i++) { // using iteration instead of for-each so that we can set the actionCommand of the button to the value of i
Album album = albums.get(i);
// attempting to create a button with the album cover as the icon
try {
// reading in image, scaling it, turning it into an icond, and adding it to the album button
Image coverImage = ImageIO.read(new File(libraryDirectory + album.getPathToCover())).getScaledInstance(200, 200, Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(coverImage);
JButton button = new JButton(album.getTitle(), icon); // including album title in button to make it easier to use
// JButton button = new JButton(icon); // would give same appearancec as in assignment spec
// make clicking the button use an action command that references the album's position in the arraylist
button.setActionCommand(String.valueOf(i));
button.addActionListener(actionListener);
albumPanel.add(button);
}
// if the album cover cannot be found, just put a text button in its place
catch (IOException e) {
JButton button = new JButton(album.getTitle());
// make clicking the button use an action command that references the album's position in the arraylist
button.setActionCommand(String.valueOf(i));
button.addActionListener(actionListener);
albumPanel.add(button);
}
}
// display the album panel
container.add(albumPanel, BorderLayout.CENTER);
setVisible(true);
}
/**
* method to load all the Albums into memory as an ArrayList of Albums
* @param libraryPath String representing the file path to the music_library.txt file
* @throws IOException if reading the albums in from the library file and/or instantiating them fails
*/
public ArrayList<Album> loadAlbums(String libraryPath) throws IOException {
// it's not really necessary that libraryPath be passed to this method from a design perspective, as they are both members of the MusicLibrary object class
// however, this makes the method more re-usable if we ever want to load albums from outside of this class
ArrayList<Album> albums = new ArrayList<>(); // ArrayList of Album objects to be returned
// instantiating an Album object for each line in the library file
BufferedReader reader = new BufferedReader(new FileReader(libraryPath)); // not catching FileNotFoundException as entire method should fail if the library file is not accessible
String line;
while ((line = reader.readLine()) != null) {
String[] columns = line.split(",");
// creating the album object and adding it to the ArrayList
albums.add(new Album(columns[0].trim(), columns[1].trim(), columns[2].trim(), libraryDirectory + columns[3].trim())); // trimming whitespace from the ends of each column read in
}
return albums;
}
/**
* method to generate a JPanel containing a JTable of all the tracks for a given Album
* @param album the Album for which we are generating a JTable of tracks
* @return a JPanel containing a JTable of all the tracks for a given Album
*/
public JPanel generateTrackPanel(Album album) {
JPanel trackPanel = new JPanel(new BorderLayout()); // using border layout so the table can be easily aligned above the "back" button
ArrayList<Track> tracks = album.getTracks();
// columns to be displayed in JTable
String[][] data = new String[tracks.size()][3];
// filling up columns to be displayed in JTable
for (int i = 0; i < tracks.size(); i++) {
// track number, track title, and track duration
data[i] = new String[]{tracks.get(i).getTrackNumber(), tracks.get(i).getTitle(), tracks.get(i).getDuration()};
}
// adding the JTable of tracks to the center of the panel
String[] columnNames = {"No.", "Track Title", "Length"};
JTable table = new JTable(data, columnNames);
table.setEnabled(false); // disable user interaction with the table so they can't edit it
trackPanel.add(new JScrollPane(table), BorderLayout.CENTER);
JButton button = new JButton("Back");
// make clicking the button use an action command that references the album's position in the arraylist
button.addActionListener(actionListener);
button.setActionCommand("showAlbumPanel");
// adding the back button to the bottom of the panel, underneath the table
trackPanel.add(button, BorderLayout.SOUTH);
return trackPanel;
}
/**
* main method
* @param args (none)
*/
public static void main(String[] args) {
MusicLibrary application = new MusicLibrary();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

View File

@ -0,0 +1,72 @@
// Name: Andrew Hayes
// Student ID: 21321503
/**
* class to represent a Track on an Album
* not really necessary for this assignmenet, could've just stored tracks as Strings or something, but i feel that this is a more "correct" OOP-like approach
*/
public class Track {
private String trackNumber; // storing as String as we never manipulate it arithmetically, and allows non-integer numberings such as A1 and B1 for A-sides and B-sides
private String title; // title of track
private String duration; // duration can also be stored as String as we never manipulate it. if manipulation was being done, java.time.Duration would be a better choice
/**
* constructor for Track objects
* @param trackNumber the number of the track as a String
* @param title the name of the track/song
* @param duration the length of the song as a String
*/
public Track(String trackNumber, String title, String duration) {
this.trackNumber = trackNumber;
this.title = title;
this.duration = duration;
}
/**
* getter method for the number of the track
* @return the number of the track as a String
*/
public String getTrackNumber() {
return trackNumber;
}
/**
* setter method for the number of the track
* @param trackNumber a String representing the number of the track
*/
public void setTrackNumber(String trackNumber) {
this.trackNumber = trackNumber;
}
/**
* getter method for the title of the track
* @return the name of the track, as a String
*/
public String getTitle() {
return title;
}
/**
* setter method for the title of the track
* @param title a String object representing the name of the track
*/
public void setTitle(String title) {
this.title = title;
}
/**
* getter method for the duration of the track
* @return the duration of the track, as a String object
*/
public String getDuration() {
return duration;
}
/**
* setter method for the duration of the track
* @param duration a String object representing the duration of the track
*/
public void setDuration(String duration) {
this.duration = duration;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB