Added basic functionality for opening files, zooming, full-screen, switching through images

This commit is contained in:
_N0x 2021-02-12 23:38:01 +01:00
parent 5ec0f50305
commit 3c6870074d
5 changed files with 261 additions and 119 deletions

View File

@ -1,6 +1,11 @@
package de.thm.tlf.photoViewer; package de.thm.tlf.photoViewer;
import de.thm.tlf.photoViewer.data.PicturePreview;
import javafx.application.Application; import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
//import javafx.beans.value.ChangeListener;
///import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@ -8,20 +13,62 @@ import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.io.File;
import java.util.List;
/** /**
* Controller Class for Image-viewer. * Controller Class for Image-viewer.
* Holds controls for the GUI elements. * Holds GUI elements
* *
* @author Tim Lukas Förster * @author Tim Lukas Förster
* @version 0.1
*/ */
public class Controller extends Application { public class Controller extends Application {
private PictureHandler picHandler = new PictureHandler(); // CENTER //
private final DoubleProperty zoomProperty = new SimpleDoubleProperty(200);
private final ScrollPane currentViewSP = new ScrollPane();
private final ImageView centerImageView = new ImageView();
// LEFT //
private final VBox leftPane = new VBox();
private final VBox selectionPane = new VBox();
private final ScrollPane pictureSelector = new ScrollPane();
// TOP //
private final VBox menu = new VBox();
private final MenuBar menuBar = new MenuBar();
private final Menu fileMenu = new Menu("File");
private final Menu aboutMenu = new Menu("About");
private final MenuItem openFiles = new MenuItem("Open");
private final MenuItem startSlideShow = new MenuItem("Start Slide Show");
private final MenuItem exitViewer = new Menu("Exit");
private final MenuItem showInfo = new Menu("Information");
// BOTTOM //
private final BorderPane bottomPanel = new BorderPane();
private final HBox bottomLeft = new HBox();
private final HBox bottomMid = new HBox();
private final HBox bottomRight = new HBox();
private Slider zoomSlider;
private final Button openFilesButton = new Button("Open Pictures");
private final Button prevPicBtn = new Button("<-");
private final Button nextPicBtn = new Button("->");
private final Button slideShowBtn = new Button("Slide Show");
private final Button fullScreenBtn = new Button("Fullscreen");
// Picture handling //
private PictureHandler picHandler;
public static void main(String[] args) { public static void main(String[] args) {
launch(args); launch(args);
@ -29,105 +76,121 @@ public class Controller extends Application {
@Override @Override
public void start(Stage primaryStage) { public void start(Stage primaryStage) {
/* ############################## picHandler = new PictureHandler();
* #### MAIN PANE ####
* #############################*/
BorderPane mainPane = new BorderPane();
// #### END MAIN PANE ####
BorderPane root = new BorderPane();
root.setLeft(createLeft());
root.setCenter(createCenter());
root.setTop(createTop());
root.setBottom(createBottom());
Scene mainScene = new Scene(root, 1200, 800);
/* ############################## //// Keypress Actions ////
* #### BOTTOM PANEL #### mainScene.setOnKeyPressed(event -> {
* #############################*/ switch (event.getCode()) {
BorderPane bottom = new BorderPane(); case RIGHT:
bottom.setPadding(new Insets(5,5,5,5)); try{
centerImageView.setImage(picHandler.getPrevPicture().getImage());
// ZoomSlider -> Bottom Left }
HBox bottomLeft = new HBox(); catch (NoPicturesLoadedException npl){ npl.printStackTrace();}
Slider zoomSlider = new Slider(0, 100, 15); break;
zoomSlider.setShowTickMarks(true); case LEFT:
// Open Button try{
Button openFilesButton = new Button("Open Pictures"); centerImageView.setImage(picHandler.getNextPicture().getImage());
}
bottomLeft.getChildren().addAll(openFilesButton, zoomSlider); catch (NoPicturesLoadedException npl){ npl.printStackTrace();}
bottom.setLeft(bottomLeft); break;
HBox bottomMid = new HBox();
bottomMid.setAlignment(Pos.CENTER);
bottomMid.setSpacing(5);
Button prevPicBtn = new Button("<-");
Button nextPicBtn = new Button("->");
Button diashowBtn = new Button("Diashow");
bottomMid.getChildren().addAll(prevPicBtn, diashowBtn, nextPicBtn);
bottom.setCenter(bottomMid);
HBox bottomRight = new HBox();
Button fullScreenBtn = new Button("Fullscreen");
bottomRight.getChildren().add(fullScreenBtn);
bottom.setRight(bottomRight);
//Button Actions
prevPicBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
picHandler.nextPicture();
} }
}); });
mainPane.setBottom(bottom); //// End Keypress Actions ////
// #### END BOTTOM PANEL ####
//// Center Zoom Action ////
zoomProperty.addListener(observable -> {
centerImageView.setFitWidth(zoomProperty.get());
centerImageView.setFitHeight(zoomProperty.get());
//centerImageView.setFitWidth(zoomProperty.get() * 4);
//centerImageView.setFitHeight(zoomProperty.get() * 3);
});
zoomSlider.valueProperty().addListener((observableValue, oldVal, newVal) -> {
if (oldVal.doubleValue() < newVal.doubleValue()){
zoomProperty.set(zoomProperty.get() + 10);
}
else if (oldVal.doubleValue() > newVal.doubleValue()){
zoomProperty.set(zoomProperty.get() - 10);
}
});
/* Currently not used. A method that allow scrolling with the mouse wheel when inside the center
currentViewSP.addEventFilter(ScrollEvent.ANY, scrollEvent -> {
if (scrollEvent.getDeltaY() > 0) {
zoomProperty.set(zoomProperty.get() * 1.1);
} else if (scrollEvent.getDeltaY() < 0) {
zoomProperty.set(zoomProperty.get() / 1.1);
}
});
/**/
//// End Center Zoom Action ////
//// Menu Actions ////
openFiles.setOnAction(openFileDialog(primaryStage));
//// End Menu Actions ////
/* ############################## //// Button Actions ////
* #### TOP PANEL #### openFilesButton.setOnAction(openFileDialog(primaryStage));
* #############################*/
VBox menu = new VBox();
// File Menu
Menu fileMenu = new Menu("File");
MenuItem openFiles = new MenuItem("Open");
MenuItem startDiashow = new MenuItem("Start Diashow");
MenuItem exitViewer = new Menu("Exit");
SeparatorMenuItem sep = new SeparatorMenuItem();
fileMenu.getItems().addAll(openFiles, sep, startDiashow, exitViewer);
// About Menu
Menu aboutMenu = new Menu("About");
MenuItem showInfo = new Menu("Information");
aboutMenu.getItems().addAll(showInfo);
// Menu bare
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(fileMenu, aboutMenu);
// Adding Menus to Top Panel
menu.getChildren().addAll(menuBar);
mainPane.setTop(menu);
// #### END TOP PANEL ####
prevPicBtn.setOnAction(e -> {
try{
centerImageView.setImage(picHandler.getPrevPicture().getImage());
}
catch (NoPicturesLoadedException npl){ npl.printStackTrace();}
});
/* ############################## nextPicBtn.setOnAction(e -> {
* #### CENTER PANEL #### try{
* #############################*/ centerImageView.setImage(picHandler.getNextPicture().getImage());
Picture testPic = new Picture("pic/image3.jpg"); }
ScrollPane currentViewSP = new ScrollPane(); catch (NoPicturesLoadedException npl){ npl.printStackTrace();}
Image image = testPic.getImage(); });
//Creating the image view
ImageView imageView = new ImageView();
//Setting image to the image view
imageView.setImage(image);
//Setting the image view parameters
imageView.setX(10);
imageView.setY(10);
imageView.setPreserveRatio(true);
currentViewSP.setContent(imageView);
mainPane.setCenter(currentViewSP);
// #### END CENTER PANEL ####
fullScreenBtn.setOnAction(e -> primaryStage.setFullScreen(true));
//// End Button Actions ////
/* ############################## primaryStage.setTitle("Photo Viewer");
* #### LEFT PANEL #### primaryStage.setScene(mainScene);
* #############################*/ primaryStage.show();
VBox leftPane = new VBox(); }
VBox selectionPane = new VBox();
selectionPane.setPadding(new Insets(5,5,5,5));
selectionPane.setSpacing(5);
// Add all previews to the /**
* Open file-dialog allowing to select multiple pictures (via filter),
* adds them to the PictureHandler and updates the picture preview
* @param stage the primary stage, used to display the file-open-dialog
* @return EventHandler for dialog handling
*/
private EventHandler<ActionEvent> openFileDialog(Stage stage) {
return e -> {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Pictures");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"));
List<File> selectedPictures = fileChooser.showOpenMultipleDialog(stage);
if (selectedPictures != null) {
try{
picHandler.loadPictures(selectedPictures);
Controller.this.updatePreviewView();
centerImageView.setImage(picHandler.getNextPicture().getImage());
}
catch (NoPicturesLoadedException npl){ npl.printStackTrace();}
}
};
}
/**
*
*/
private void updatePreviewView(){
for(PicturePreview pp: picHandler.getPreviews()){ for(PicturePreview pp: picHandler.getPreviews()){
ImageView iv = new ImageView(pp.getImage()); ImageView iv = new ImageView(pp.getImage());
iv.setFitWidth(150); iv.setFitWidth(150);
@ -135,16 +198,71 @@ public class Controller extends Application {
iv.setPreserveRatio(true); iv.setPreserveRatio(true);
selectionPane.getChildren().add(iv); selectionPane.getChildren().add(iv);
} }
ScrollPane pictureSelector = new ScrollPane(); }
/**
* Method that handles the settings and layout of the Left Panel
* @return Node, set up for displaying on the left of a GridPane
*/
private Node createLeft(){
selectionPane.setPadding(new Insets(5,5,5,5));
selectionPane.setSpacing(5);
pictureSelector.setContent(selectionPane); pictureSelector.setContent(selectionPane);
leftPane.getChildren().addAll(pictureSelector); leftPane.getChildren().addAll(pictureSelector);
mainPane.setLeft(leftPane); return leftPane;
// #### END LEFT PANEL ####
primaryStage.setTitle("Photo Viewer");
primaryStage.setScene(new Scene(mainPane, 1200, 600));
primaryStage.show();
} }
/**
* Method that handles the settings and layout of the top Panel
* @return Node, set up for displaying on the top of a GridPane
*/
private Node createTop(){
SeparatorMenuItem sep = new SeparatorMenuItem();
fileMenu.getItems().addAll(openFiles, sep, startSlideShow, exitViewer);
// About Menu
aboutMenu.getItems().addAll(showInfo);
// Menu bare
menuBar.getMenus().addAll(fileMenu, aboutMenu);
// Adding Menus to Top Panel
menu.getChildren().addAll(menuBar);
return menu;
}
/**
* Method that handles the settings and layout of the center Panel
* @return Node, set up for displaying on the center of a GridPane
*/
private Node createCenter(){
centerImageView.setX(10);
centerImageView.setY(10);
centerImageView.setPreserveRatio(true);
currentViewSP.setContent(centerImageView);
return currentViewSP;
}
/**
* Method that handles the settings and layout of the bottom Panel
* @return Node, set up for displaying on the bottom of a GridPane
*/
private Node createBottom() {
bottomPanel.setPadding(new Insets(5, 5, 5, 5));
// Left Bottom Part
zoomSlider = new Slider(0, 100, 25);
zoomSlider.setShowTickMarks(true);
bottomLeft.getChildren().addAll(openFilesButton, zoomSlider);
bottomPanel.setLeft(bottomLeft);
// Middle Bottom Part
bottomMid.setAlignment(Pos.CENTER);
bottomMid.setSpacing(5);
bottomMid.getChildren().addAll(prevPicBtn, slideShowBtn, nextPicBtn);
bottomPanel.setCenter(bottomMid);
// Right Bottom Part
bottomRight.getChildren().add(fullScreenBtn);
bottomPanel.setRight(bottomRight);
return (bottomPanel);
}
} }

View File

@ -0,0 +1,7 @@
package de.thm.tlf.photoViewer;
public class NoPicturesLoadedException extends Exception{
NoPicturesLoadedException(String s){
super(s);
}
}

View File

@ -1,29 +1,48 @@
package de.thm.tlf.photoViewer; package de.thm.tlf.photoViewer;
import de.thm.tlf.photoViewer.data.Picture;
import de.thm.tlf.photoViewer.data.PicturePreview;
import java.io.File;
import java.util.*;
public class PictureHandler { public class PictureHandler {
private PicturePreview[] previews = new PicturePreview[]{ private ArrayList<Picture> pictures = new ArrayList<>();
new PicturePreview("pic/image1.jpg"), private ArrayList<PicturePreview> previews = new ArrayList<>();
new PicturePreview("pic/image2.jpg"),
new PicturePreview("pic/image3.jpg")
};
private int currentPictureID = 0; private int currentPictureID = -1;
public PicturePreview[] getPreviews(){ public ArrayList<PicturePreview> getPreviews(){
return previews; return previews;
} }
public void loadPictures(){ public void loadPictures(List<File> pictureFiles){
for(File picFile : pictureFiles){
pictures.add(new Picture(picFile.getPath()));
previews.add(new PicturePreview(picFile.getPath()));
}
} }
public Picture nextPicture(){ public Picture getNextPicture() throws NoPicturesLoadedException {
return null; if(pictures.size() <= 0){
throw new NoPicturesLoadedException("No pictures have been loaded");
}
else {
currentPictureID = (currentPictureID + 1) % pictures.size();
return pictures.get(currentPictureID);
}
} }
public Picture prevPicture(){ public Picture getPrevPicture() throws NoPicturesLoadedException{
return null; if(pictures.size() <= 0){
throw new NoPicturesLoadedException("No pictures have been loaded");
}
else {
currentPictureID = (currentPictureID + pictures.size() - 1) % pictures.size();
return pictures.get(currentPictureID);
}
}
} }
}

View File

@ -1,4 +1,4 @@
package de.thm.tlf.photoViewer; package de.thm.tlf.photoViewer.data;
import javafx.scene.image.Image; import javafx.scene.image.Image;

View File

@ -1,6 +1,4 @@
package de.thm.tlf.photoViewer; package de.thm.tlf.photoViewer.data;
import java.io.FileInputStream;
public class PicturePreview extends Picture{ public class PicturePreview extends Picture{