diff --git a/hw3/src/PhotoAlbumApp.java b/hw3/src/PhotoAlbumApp.java index 6da1d8c..0eb660f 100644 --- a/hw3/src/PhotoAlbumApp.java +++ b/hw3/src/PhotoAlbumApp.java @@ -1,8 +1,16 @@ import controller.PhotoAlbumController; import model.PhotoAlbumModel; -import strategy.SortByDate; import view.PhotoAlbumView; + +/** + * Photo Album Manager application entry point. + *
+ * This class creates the model, view, and controller objects and initializes the view. + * + * @author Yuri Tatishchev + * @version 0.1 2025-03-26 + */ public class PhotoAlbumApp { public static void main(String[] args) { // Create MVC components @@ -16,4 +24,4 @@ public class PhotoAlbumApp { // Display the main window javax.swing.SwingUtilities.invokeLater(() -> view.setVisible(true)); } -} \ No newline at end of file +} diff --git a/hw3/src/controller/PhotoAlbumController.java b/hw3/src/controller/PhotoAlbumController.java index a67e16f..0a02a89 100644 --- a/hw3/src/controller/PhotoAlbumController.java +++ b/hw3/src/controller/PhotoAlbumController.java @@ -12,22 +12,55 @@ import javax.swing.filechooser.FileNameExtensionFilter; import java.io.File; import java.util.Date; +/** + * A controller that manages interactions between the photo album model and view. + *
+ * This class handles user actions from the view, such as adding and deleting photos, + * navigating through the album, and changing the sorting strategy. + * It acts as an intermediary between the {@link PhotoAlbumModel} and {@link PhotoAlbumView}, + * translating user interface events into model operations. + * + * @author Yuri Tatishchev + * @version 0.1 2025-03-26 + * @see PhotoAlbumModel + * @see PhotoAlbumView + * @see Photo + */ public class PhotoAlbumController { private final PhotoAlbumModel model; private final PhotoAlbumView view; + /** + * Constructs a new photo album controller. + * + * @param model the photo album model to control + * @param view the view to handle user interactions + */ public PhotoAlbumController(PhotoAlbumModel model, PhotoAlbumView view) { this.model = model; this.view = view; } + /** + * Returns the photo album model being controlled. + * + * @return the photo album model + */ public PhotoAlbumModel getModel() { return model; } + /** + * Handles the addition of a new photo to the album. + * Opens a file chooser dialog for selecting an image file and + * prompts for a photo name. + */ public void handleAddPhoto() { JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Image files", "jpg", "jpeg", "png", "gif")); + fileChooser.setFileFilter(new FileNameExtensionFilter( + "Image files", + "jpg", "jpeg", "png", "gif" + )); if (fileChooser.showOpenDialog(view) == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); @@ -45,6 +78,10 @@ public class PhotoAlbumController { } } + /** + * Handles the deletion of a photo from the album. + * Prompts for the name of the photo to delete. + */ public void handleDeletePhoto() { String name = JOptionPane.showInputDialog(view, "Enter photo name to delete:"); if (name != null && !name.trim().isEmpty()) { @@ -52,18 +89,36 @@ public class PhotoAlbumController { } } + /** + * Handles navigation to the next photo in the album. + * Moves to the next photo if one exists. + */ public void handleNext() { if (model.hasNext()) { model.next(); } } + /** + * Handles navigation to the previous photo in the album. + * Moves to the previous photo if one exists. + */ public void handlePrevious() { if (model.hasPrevious()) { model.previous(); } } + /** + * Handles changing the sorting strategy for photos in the album. + * + * @param strategy the sorting strategy to use: + *
+ * This class provides functionality to traverse a list of photos in both + * forward and backward directions. It maintains a current position and + * provides methods to check for the existence of next and previous photos, + * as well as to retrieve the current, next, and previous photos. + *
+ * The iterator throws {@link NoSuchElementException} when attempting to
+ * access elements beyond the bounds of the photo list.
+ *
+ * @author Yuri Tatishchev
+ * @version 0.1 2025-03-26
+ * @see Photo
+ * @see AlbumIterator
+ * @see NoSuchElementException
+ */
public class PhotoIterator implements AlbumIterator {
private final List
+ * A photo has a:
+ *
+ * A photo is immutable.
+ *
+ * @author Yuri Tatishchev
+ * @version 0.1 2022-03-26
+ */
public record Photo(String name, String filePath, Date dateAdded, long fileSize) {
}
diff --git a/hw3/src/model/PhotoAlbumModel.java b/hw3/src/model/PhotoAlbumModel.java
index 67c211c..015b6d4 100644
--- a/hw3/src/model/PhotoAlbumModel.java
+++ b/hw3/src/model/PhotoAlbumModel.java
@@ -3,15 +3,40 @@ package model;
import strategy.SortingStrategy;
import iterator.AlbumIterator;
import iterator.PhotoIterator;
+
import java.util.*;
+/**
+ * A model that represents a photo album.
+ *
+ * This class is responsible for managing the photos in the album, as well as
+ * the sorting strategy used to sort the photos.
+ * The model notifies its listeners when the model changes.
+ * It also provides methods to add and delete photos,
+ * as well as to navigate through the photos.
+ *
+ * @author Yuri Tatishchev
+ * @version 0.1 2025-03-26
+ * @see Photo
+ * @see SortingStrategy
+ * @see AlbumIterator
+ * @see PhotoIterator
+ * @see ModelChangeListener
+ */
public class PhotoAlbumModel {
private List
+ * This class is responsible for displaying the photo album's graphical interface,
+ * including the list of photos, current photo display, and control buttons.
+ * The view implements the {@link PhotoAlbumModel.ModelChangeListener} interface
+ * to receive notifications of model changes.
+ *
+ * The view provides user interface components for:
+ *
+ * Sets up the frame properties, creates buttons, list components,
+ * and initializes them with default states.
+ */
private void initializeComponents() {
setTitle("Photo Album Manager");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -47,8 +76,6 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
String[] sortOptions = {"Sort by Name", "Sort by Date", "Sort by Size"};
sortingCombo = new JComboBox<>(sortOptions);
- // Select default sorting option
- sortingCombo.setSelectedIndex(1);
listModel = new DefaultListModel<>();
photoList = new JList<>(listModel);
@@ -57,6 +84,17 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
photoList.setFixedCellHeight(60); // Accommodate thumbnails
}
+
+ /**
+ * Sets up the layout of the photo album view.
+ *
+ * Arranges the UI components using BorderLayout with:
+ *
+ * Attaches the controller to the view and sets up event listeners
+ * for the control buttons and sorting combo box.
+ *
+ * @param controller the controller to set
+ */
public void setController(PhotoAlbumController controller) {
this.model = controller.getModel();
model.addListener(this);
@@ -89,6 +135,9 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
nextButton.addActionListener(e -> controller.handleNext());
previousButton.addActionListener(e -> controller.handlePrevious());
sortingCombo.addActionListener(e -> controller.handleSort(sortingCombo.getSelectedIndex()));
+
+ // Select default sorting option
+ sortingCombo.setSelectedIndex(1);
}
@Override
@@ -98,6 +147,12 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
updateNavigationButtons();
}
+ /**
+ * Updates the list of photos displayed in the sidebar.
+ *
+ * Clears the current list model and populates it with
+ * names of photos from the model.
+ */
private void updatePhotoList() {
listModel.clear();
List
+ * If a photo is selected, loads and displays its image.
+ * If loading fails, displays an error message.
+ * If no photo is selected, displays a default message.
+ */
private void updateCurrentPhoto() {
Photo current = model.getCurrentPhoto();
if (current != null) {
@@ -123,12 +185,27 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
}
}
+ /**
+ * Updates the enabled state of navigation buttons.
+ *
+ * Enables or disables the previous/next buttons based on
+ * the current position in the photo album.
+ * Enables the delete button only when the album is not empty.
+ */
private void updateNavigationButtons() {
previousButton.setEnabled(model.hasPrevious());
nextButton.setEnabled(model.hasNext());
deleteButton.setEnabled(model.getCurrentPhoto() != null);
}
+ /**
+ * Loads and scales an image from the given path.
+ *
+ * Creates a scaled version of the image suitable for the main display area.
+ *
+ * @param path the file path of the image to load
+ * @return a scaled ImageIcon, or null if loading fails
+ */
private ImageIcon loadImage(String path) {
try {
ImageIcon icon = new ImageIcon(path);
@@ -140,6 +217,18 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
}
}
+ /**
+ * A custom list cell renderer for displaying photos with thumbnails and details.
+ *
+ * This inner class renders each photo in the list with:
+ *
+ * It also implements thumbnail caching to improve performance.
+ */
private class PhotoListCellRenderer extends JPanel implements ListCellRenderer
+ * Converts the size to kilobytes or megabytes with one decimal place.
+ *
+ * @param size the file size in bytes
+ * @return a formatted string with the size in KB or MB
+ */
private String formatFileSize(long size) {
if (size < 1024 * 1024) {
return String.format("%.1f KB", size / 1024.0);
@@ -195,6 +296,14 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
}
}
+ /**
+ * Loads and scales a thumbnail image from the given path.
+ *
+ * Creates a scaled version of the image suitable for the list display.
+ *
+ * @param path the file path of the image to load
+ * @return a scaled ImageIcon, or null if loading fails
+ */
private ImageIcon loadThumbnail(String path) {
try {
ImageIcon icon = new ImageIcon(path);
+ *
+ *
+ *
+ *
+ * @author Yuri Tatishchev
+ * @version 0.1 2025-03-26
+ * @see PhotoAlbumModel
+ * @see PhotoAlbumController
+ * @see Photo
+ */
public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChangeListener {
private PhotoAlbumModel model;
@@ -27,6 +50,12 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
setupLayout();
}
+ /**
+ * Initializes all UI components of the photo album view.
+ *
+ *
+ */
private void setupLayout() {
setLayout(new BorderLayout());
@@ -80,6 +118,14 @@ public class PhotoAlbumView extends JFrame implements PhotoAlbumModel.ModelChang
add(controlPanel, BorderLayout.SOUTH);
}
+ /**
+ * Sets the controller for the photo album view.
+ *
+ *
+ *