diff --git a/src/de/thm/tlf/photoViewer/Controller.java b/src/de/thm/tlf/photoViewer/Controller.java index 8e288d3..4b038a5 100644 --- a/src/de/thm/tlf/photoViewer/Controller.java +++ b/src/de/thm/tlf/photoViewer/Controller.java @@ -2,10 +2,12 @@ package de.thm.tlf.photoViewer; import de.thm.tlf.photoViewer.data.PicturePreview; import javafx.application.Application; +import javafx.application.Platform; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; //import javafx.beans.value.ChangeListener; -///import javafx.beans.value.ObservableValue; +//import javafx.beans.value.ObservableValue; +import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; @@ -23,14 +25,13 @@ import java.util.List; /** * Controller Class for Image-viewer. - * Holds GUI elements + * Holds GUI elements as well as the handling of any user input. * * @author Tim Lukas Förster * @version 0.1 */ - public class Controller extends Application { - + //------ Attributes ------// // CENTER // private final DoubleProperty zoomProperty = new SimpleDoubleProperty(200); private final ScrollPane currentViewSP = new ScrollPane(); @@ -57,8 +58,8 @@ public class Controller extends Application { private final HBox bottomMid = new HBox(); private final HBox bottomRight = new HBox(); - private Slider zoomSlider; private final Button openFilesButton = new Button("Open Pictures"); + private Slider zoomSlider; private final Button prevPicBtn = new Button("<-"); private final Button nextPicBtn = new Button("->"); @@ -69,14 +70,19 @@ public class Controller extends Application { // Picture handling // private PictureHandler picHandler; + // Etc. // + private boolean bIsFullScreen = false; + private boolean bSlideShowActive = false; + //------ End Attributes ------// + //------ Methods ------// public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { - picHandler = new PictureHandler(); + picHandler = PictureHandler.getInstance(); BorderPane root = new BorderPane(); root.setLeft(createLeft()); @@ -85,31 +91,33 @@ public class Controller extends Application { root.setBottom(createBottom()); Scene mainScene = new Scene(root, 1200, 800); - //// Keypress Actions //// + // Keypress Actions // mainScene.setOnKeyPressed(event -> { switch (event.getCode()) { case RIGHT: try{ centerImageView.setImage(picHandler.getPrevPicture().getImage()); } - catch (NoPicturesLoadedException npl){ npl.printStackTrace();} + catch (NoPicturesLoadedException npl) { showNoPicturesLoadedWarning(); } break; case LEFT: try{ centerImageView.setImage(picHandler.getNextPicture().getImage()); } - catch (NoPicturesLoadedException npl){ npl.printStackTrace();} + catch (NoPicturesLoadedException npl) { showNoPicturesLoadedWarning(); } break; } }); - //// End Keypress Actions //// + // End Keypress Actions // - //// Center Zoom Action //// + // Center Zoom Action // zoomProperty.addListener(observable -> { centerImageView.setFitWidth(zoomProperty.get()); centerImageView.setFitHeight(zoomProperty.get()); - //centerImageView.setFitWidth(zoomProperty.get() * 4); - //centerImageView.setFitHeight(zoomProperty.get() * 3); + /* Previously used values + centerImageView.setFitWidth(zoomProperty.get() * 4); + centerImageView.setFitHeight(zoomProperty.get() * 3); + */ }); zoomSlider.valueProperty().addListener((observableValue, oldVal, newVal) -> { @@ -131,38 +139,81 @@ public class Controller extends Application { } }); /**/ - //// End Center Zoom Action //// + // End Center Zoom Action // - //// Menu Actions //// + // Menu Actions // openFiles.setOnAction(openFileDialog(primaryStage)); - //// End Menu Actions //// + exitViewer.setOnAction( e -> Platform.exit()); + // End Menu Actions // - //// Button Actions //// + // Button Actions // openFilesButton.setOnAction(openFileDialog(primaryStage)); prevPicBtn.setOnAction(e -> { try{ centerImageView.setImage(picHandler.getPrevPicture().getImage()); } - catch (NoPicturesLoadedException npl){ npl.printStackTrace();} + catch (NoPicturesLoadedException npl){ showNoPicturesLoadedWarning();} }); nextPicBtn.setOnAction(e -> { try{ centerImageView.setImage(picHandler.getNextPicture().getImage()); } - catch (NoPicturesLoadedException npl){ npl.printStackTrace();} + catch (NoPicturesLoadedException npl){ showNoPicturesLoadedWarning();} }); - fullScreenBtn.setOnAction(e -> primaryStage.setFullScreen(true)); - //// End Button Actions //// + fullScreenBtn.setOnAction(e -> { + primaryStage.setFullScreen(!bIsFullScreen); + bIsFullScreen ^= true; + }); + + slideShowBtn.setOnAction(new EventHandler<>() { + Thread th; + + @Override + public void handle(ActionEvent actionEvent) { + try { + // This statement is to catch any errors regarding no images loaded + centerImageView.setImage(picHandler.getNextPicture().getImage()); + + if (!bSlideShowActive) { + bSlideShowActive = true; + slideShowBtn.setText("Stop Slide Show"); + th = new Thread(slideShowTask); + th.start(); + } else { + bSlideShowActive = false; + slideShowBtn.setText("Slide Show"); + th.interrupt(); + } + } catch (NoPicturesLoadedException npl){ + showNoPicturesLoadedWarning(); + } + } + }); + // End Button Actions // primaryStage.setTitle("Photo Viewer"); primaryStage.setScene(mainScene); primaryStage.show(); } + @SuppressWarnings("rawtypes") + Task slideShowTask = new Task(){ + @Override + @SuppressWarnings("BusyWait") + protected Void call() throws Exception { + while(bSlideShowActive) { + Thread.sleep(3000); + centerImageView.setImage(picHandler.getNextPicture().getImage()); + } + return null; + } + }; + + //------ Helper-Methods ------// /** * Open file-dialog allowing to select multiple pictures (via filter), * adds them to the PictureHandler and updates the picture preview @@ -182,13 +233,13 @@ public class Controller extends Application { Controller.this.updatePreviewView(); centerImageView.setImage(picHandler.getNextPicture().getImage()); } - catch (NoPicturesLoadedException npl){ npl.printStackTrace();} + catch (NoPicturesLoadedException npl){ showNoPicturesLoadedWarning();} } }; } /** - * + * Method that updates the preview Pane with all PreviewPictures provided by the Picture Handler */ private void updatePreviewView(){ for(PicturePreview pp: picHandler.getPreviews()){ @@ -265,4 +316,19 @@ public class Controller extends Application { bottomPanel.setRight(bottomRight); return (bottomPanel); } + + /** + * Displays a warning dialogue informing the user that no pictures has been loaded yet + * and the executed action is not possible. + */ + private void showNoPicturesLoadedWarning(){ + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.setTitle("No pictures loaded"); + alert.setContentText("No pictures have been loaded" + + "\nPlease select pictures via the menu or via the open button to view them."); + alert.showAndWait().ifPresent(rs -> { + }); + } + //------ End Helper-Methods ------// + //------ End Methods ------// } diff --git a/src/de/thm/tlf/photoViewer/NoPicturesLoadedException.java b/src/de/thm/tlf/photoViewer/NoPicturesLoadedException.java index 0972fbd..99e6faa 100644 --- a/src/de/thm/tlf/photoViewer/NoPicturesLoadedException.java +++ b/src/de/thm/tlf/photoViewer/NoPicturesLoadedException.java @@ -1,5 +1,9 @@ package de.thm.tlf.photoViewer; +/** + * Exception for handling errors when no pictures are loaded into the program + * but any of the actions that involve pictures are performed. + */ public class NoPicturesLoadedException extends Exception{ NoPicturesLoadedException(String s){ super(s); diff --git a/src/de/thm/tlf/photoViewer/PictureHandler.java b/src/de/thm/tlf/photoViewer/PictureHandler.java index 5d93181..7d6c1a0 100644 --- a/src/de/thm/tlf/photoViewer/PictureHandler.java +++ b/src/de/thm/tlf/photoViewer/PictureHandler.java @@ -6,13 +6,30 @@ import de.thm.tlf.photoViewer.data.PicturePreview; import java.io.File; import java.util.*; -public class PictureHandler { - - private ArrayList pictures = new ArrayList<>(); - private ArrayList previews = new ArrayList<>(); +/** + * Class for handling interaction with Images + * Uses custom Image-wrappers "Picture" and "PicturePreview" + * Implemented using singleton pattern to avoid multiple instances + */ +public final class PictureHandler { + //------ Attributes ------// + private final ArrayList pictures = new ArrayList<>(); + private final ArrayList previews = new ArrayList<>(); private int currentPictureID = -1; + private static final PictureHandler INSTANCE = new PictureHandler(); + //------ End Attributes ------// + + + //------ Constructors ------// + private PictureHandler() {} + + public static PictureHandler getInstance() {return INSTANCE;} + //------ End Constructors ------// + + + //------ Methods ------// public ArrayList getPreviews(){ return previews; } @@ -40,9 +57,9 @@ public class PictureHandler { } else { currentPictureID = (currentPictureID + pictures.size() - 1) % pictures.size(); - return pictures.get(currentPictureID); } } + //------ End Methods ------// } diff --git a/src/de/thm/tlf/photoViewer/data/Picture.java b/src/de/thm/tlf/photoViewer/data/Picture.java index 26f9cbf..9245f44 100644 --- a/src/de/thm/tlf/photoViewer/data/Picture.java +++ b/src/de/thm/tlf/photoViewer/data/Picture.java @@ -6,6 +6,9 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +/** + * Data Class that is used for Image-Handling and -storing + */ public class Picture { private Image image; diff --git a/src/de/thm/tlf/photoViewer/data/PicturePreview.java b/src/de/thm/tlf/photoViewer/data/PicturePreview.java index d49cbf8..81c1513 100644 --- a/src/de/thm/tlf/photoViewer/data/PicturePreview.java +++ b/src/de/thm/tlf/photoViewer/data/PicturePreview.java @@ -1,5 +1,9 @@ package de.thm.tlf.photoViewer.data; +/** + * Wrapper of class Picture that's used for handling the preview of pictures + * -> Used to distinguish between pictures and preview + */ public class PicturePreview extends Picture{ public PicturePreview(String fileRef) {