/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package mytime.gui.controller; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXComboBox; import com.jfoenix.controls.JFXMasonryPane; import com.jfoenix.controls.JFXScrollPane; import com.jfoenix.controls.JFXSnackbar; import com.jfoenix.controls.JFXSpinner; import com.jfoenix.controls.JFXTextField; import javafx.scene.paint.Color; import java.io.IOException; import java.net.URL; import java.sql.SQLException; import java.util.List; import java.util.ResourceBundle; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.Event; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ContentDisplay; import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.effect.GaussianBlur; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.KeyEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.shape.Circle; import javafx.scene.text.Font; import mytime.be.Location; import javafx.stage.Stage; import mytime.be.Person; import mytime.gui.model.ManagerModel; import mytime.gui.model.Model; import mytime.gui.model.VolunteerModel; /** * FXML Controller class * * @author Stefan-VpcEB3J1E */ public class ManagerMainViewController implements Initializable, ChangeListener<Boolean> { @FXML private JFXTextField txtFieldSearch; @FXML private JFXScrollPane scrollPane; @FXML private JFXMasonryPane masonryPane; private ManagerModel mgrModel; private Executor exec; private ExecutorService execService; @FXML private JFXButton btnShowSidePanel; @FXML private BorderPane mainBorderPane; private Task<Node> getPane; private Node centerNode; private String oldValue; @FXML private StackPane stackPane; private SlidePanelAnimation slide; private Menu menuSort; private JFXSnackbar snackBar, undoSnackbar; private EventHandler undoChangesHandler; @FXML private JFXComboBox<Location> comboBoxNewLocation; @FXML private JFXButton btnDeleteSavedLocation; // @FXML // private JFXButton btnBackMan; private Node volunteerViewNode; //private VBox parentOfMason; private JFXScrollPane scrollPaneToSwap; @FXML private BorderPane borderPaneVolunteer; public ManagerMainViewController() { } /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { initHeaderPane(); // JFXScrollPane.smoothScrolling(scrollPane); snackBar = new JFXSnackbar(mainBorderPane); undoSnackbar = new JFXSnackbar(mainBorderPane); undoChangesHandler = (EventHandler) (Event event) -> { // try // { snackBar.close(); try { // volunteerModel.undoLastChanges(); Node lastNode = getNodeForVolunteer(mgrModel.undoLastDeletedPerson()); mgrModel.getAllPersonNodes().add(lastNode); masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes()); } catch (SQLException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } undoSnackbar.show(" Genskabte sidst slettede person med success.", 3000); // } catch (SQLException ex) // { // ex.printStackTrace(); // } }; oldValue = ""; //mgrModel.getTextfieldSearchText().bindBidirectional(txtFieldSearch.textProperty()); centerNode = mainBorderPane.getCenter(); mainBorderPane.setCenter(null); JFXSpinner spinner = new JFXSpinner(); spinner.setRadius(40); mainBorderPane.setCenter(spinner); txtFieldSearch.setVisible(false); btnShowSidePanel.setVisible(false); // btnBackMan.setVisible(false); mgrModel = ManagerModel.getInstance(); mgrModel.getSnackbarMessage().addListener(new ListChangeListener<String>() { @Override public void onChanged(ListChangeListener.Change<? extends String> c) { String name = mgrModel.getSnackbarMessage().get(mgrModel.getSnackbarMessage().size() - 1); if (name.startsWith("Slettede")) { snackBar.show(" " + name, "Fortryd?", undoChangesHandler); } else { snackBar.show(" " + name, 3500); } setOnActionCloseClick(); } }); mgrModel.getShowRightPanel().addListener(this); mgrModel.getReloadNodes().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (newValue) { masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes()); mgrModel.getReloadNodes().set(false); } } }); exec = Executors.newCachedThreadPool(runnable -> { Thread t = new Thread(runnable); t.setDaemon(true); return t; }); execService = Executors.newFixedThreadPool(4, (Runnable r) -> { Thread t = Executors.defaultThreadFactory().newThread(r); t.setDaemon(true); return t; }); setUpTask(); Platform.runLater(() -> loadAllPersonsIntoListAsNodes()); mgrModel.getObjectProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Object oldValue, Object newValue) { try { mgrModel.getAllPersonNodes().add(getNodeForVolunteer((Person) newValue)); masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes()); } catch (IOException ex) { Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex); } } }); //mgrModel.setCurrentPerson(masonryPane.get); FXMLLoader loader = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerOneVolunteerInformation.fxml")); try { volunteerViewNode = loader.load(); } catch (IOException ex) { Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex); } //parentOfMason = (VBox) masonryPane.getParent(); List<Node> nodes = borderPaneVolunteer.getChildren(); for (Node node : nodes) { if (node.getClass().getName() == JFXScrollPane.class.getName()) { System.out.println("SUCCES"); scrollPaneToSwap = (JFXScrollPane) node; } } mgrModel.getClickedVolunteer().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Object oldValue, Object newValue) { if (newValue != null) { borderPaneVolunteer.setCenter(volunteerViewNode); } else { borderPaneVolunteer.setCenter(scrollPaneToSwap); } } }); setLocationsInComboBox(); } /** * Scrollpane header. */ private void initHeaderPane() { ImageView imgV = new ImageView(new Image("/mytime/gui/view/back.png")); imgV.setPreserveRatio(true); imgV.setSmooth(true); imgV.setCache(true); JFXButton button = new JFXButton(""); button.setOnAction(e -> { handleGoBack(new ActionEvent()); }); button.setGraphic(imgV); Node topNode = mainBorderPane.getTop(); mainBorderPane.setTop(null); scrollPane.getTopBar().getChildren().add(button); // scrollPane.getTopBar().getChildren().add(topNode); try { FXMLLoader lblLoader = new FXMLLoader(getClass().getResource("/mytime/gui/view/header.fxml")); Node lblNode = lblLoader.load(); Label lblHeader = (Label) lblNode; // lblHeader.setFont(Font.font(45)); // lblHeader.setTextFill(Color.rgb(252, 252, 252, .99)); scrollPane.getBottomBar().getChildren().add(lblHeader); StackPane.setMargin(lblHeader, new Insets(0, 0, 0, 80)); StackPane.setAlignment(lblHeader, Pos.CENTER_LEFT); StackPane.setAlignment(button, Pos.CENTER_LEFT); StackPane.setMargin(button, new Insets(0, 0, 0, 20)); } catch (IOException ex) { ex.printStackTrace(); } } /** * Sets the locations in the combobox in the manger view */ private void setLocationsInComboBox() { try { ObservableList<Location> items = FXCollections.observableArrayList(); items.addAll(Model.getInstance().getAllLocations()); Image img = new Image("mytime/gui/view/css/Delete.png"); ImageView imv = new ImageView(img); imv.setPreserveRatio(true); imv.setSmooth(true); imv.setCache(true); imv.setFitHeight(8); imv.setFitWidth(8); btnDeleteSavedLocation.setGraphic(imv); btnDeleteSavedLocation.setText(""); comboBoxNewLocation.setItems(items); for (Location item : comboBoxNewLocation.getItems()) { if (item.getId().get() == VolunteerModel.getInstance().getCurrentLocation().getId().get()) { comboBoxNewLocation.getSelectionModel().clearAndSelect(comboBoxNewLocation.getItems().indexOf(item)); } } comboBoxNewLocation.setVisible(false); btnDeleteSavedLocation.setVisible(false); comboBoxNewLocation.setOnAction(e -> { if (comboBoxNewLocation.getSelectionModel().getSelectedItem() != null) { try { if (snackBar.isVisible()) { snackBar.close(); } Model.getInstance().saveLocationLocally(comboBoxNewLocation.getSelectionModel().getSelectedItem().getId().get()); snackBar.show(" " + comboBoxNewLocation.getSelectionModel().getSelectedItem().getName().get() + " blev valgt som lokation på denne computer. \n Kun en manager kan ændre denne indstilling.", 7500); } catch (IOException ex) { ex.printStackTrace(); } } }); } catch (SQLException ex) { Logger.getLogger(ManagerMainViewController.class.getName()).log(Level.SEVERE, null, ex); } } /** * Sets a timer when you click in the document hours window, and closes the * snackbar after 3.5sec. */ private void setOnActionCloseClick() { masonryPane.setOnMouseClicked(e -> { runTimerTask(); }); mainBorderPane.getTop().setOnMouseClicked(a -> { runTimerTask(); }); comboBoxNewLocation.setOnMouseClicked(e -> { runTimerTask(); }); btnShowSidePanel.setOnMouseClicked(e -> { runTimerTask(); }); } /** * Timer task */ private void runTimerTask() { TimerTask clearActions = new TimerTask() { @Override public void run() { masonryPane.setOnMouseClicked(null); } }; Timer timer2 = new Timer(true); timer2.schedule(clearActions, 3600); TimerTask timerTask = new TimerTask() { @Override public void run() { snackBar.close(); } }; Timer timer = new Timer(true); timer.schedule(timerTask, 3500); } @FXML private void handleOpenRightSidePanel(ActionEvent event) { handleOpenCloseRightSide(); } /** * Sets up the task that should be executed by our Executor, when you click * on add a new volunteer. */ private void setUpTask() { getPane = new Task<Node>() { @Override protected Node call() throws Exception { FXMLLoader newLoadedPane = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerCreateVolunteer.fxml")); Node node = newLoadedPane.load(); return node; } }; getPane.setOnSucceeded(e -> { Node paneToLoad = getPane.getValue(); if (paneToLoad != null) { Platform.runLater(() -> { slide = new SlidePanelAnimation(209, paneToLoad); mgrModel.setRightSideNode(paneToLoad); // stackPane.setAlignment(slide, Pos.CENTER_RIGHT); stackPane.getChildren().add(slide); mgrModel.getShowRightPanel().set(true); }); } }); } /** * Handles the open & close side panel. */ private void handleOpenCloseRightSide() { if (mainBorderPane.getRight() == null) { if (mgrModel.getRightSideView() == null) { exec.execute(getPane); mainBorderPane.getCenter().setEffect(new GaussianBlur()); } else { if (slide == null) { Node node = mgrModel.getRightSideView(); slide = new SlidePanelAnimation(209, node); // mainBorderPane.setRight(slide); } stackPane.getChildren().add(slide); mgrModel.getShowRightPanel().set(true); mainBorderPane.getCenter().setEffect(new GaussianBlur()); // mainBorderPane.getBottom().setEffect(new GaussianBlur()); } } else { // mainBorderPane.setRight(null); stackPane.getChildren().remove(slide); mainBorderPane.getCenter().setEffect(null); // mainBorderPane.getBottom().setEffect(null); } } /** * Method for getting a volunteer as a node, so that we can load it in our * view as a JAVAFX component. * * @param volunteer * @return * @throws IOException */ private Node getNodeForVolunteer(Person volunteer) throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("/mytime/gui/view/ManagerOneVolunteer.fxml")); Node node = loader.load(); Button button = (Button) node; ManagerOneVolunteerController controller = loader.getController(); controller.setVolunteer(volunteer); // load the image Image image = new Image(volunteer.getProfilePicture().get()); // simple displays ImageView the image as is ImageView iv1 = new ImageView(); // iv1.setFitWidth(70); iv1.setFitHeight(50); Circle clip = new Circle(iv1.getFitHeight() / 2, iv1.getFitWidth() / 3, 26); iv1.setClip(clip); iv1.setImage(image); iv1.setPreserveRatio(true); iv1.setSmooth(true); iv1.setCache(true); button.setPrefHeight(40); button.setPrefWidth(150); button.getStyleClass().add("VolunteerBtn"); String firstName = volunteer.getFirstName().get(); String lastName = volunteer.getLastName().get(); button.setText(""); StackPane grap = new StackPane(); HBox vbox = new HBox(); vbox.setAlignment(Pos.CENTER_LEFT); vbox.setSpacing(4); Label lblName = new Label(); lblName.setText(firstName + "\n" + lastName); vbox.getChildren().addAll(iv1, lblName); grap.setAlignment(Pos.CENTER_LEFT); grap.getChildren().add(vbox); button.setGraphic(grap); button.setContentDisplay(ContentDisplay.LEFT); button.setUserData(volunteer); // Timeline animation = new Timeline(new KeyFrame(Duration.millis(240), new KeyValue(button.scaleXProperty(), 1, Interpolator.EASE_BOTH), // new KeyValue(button.scaleYProperty(), 1, Interpolator.EASE_BOTH))); // animation.setDelay(Duration.millis(100 * 2 + (2000))); // animation.play(); return node; } /** * Loads all the persons with the same Location ID in as nodes in a list in * the Volunteer Model. */ private void loadAllPersonsIntoListAsNodes() { Task<List<Person>> loadPersonAsGUIComponentsTask = new Task<List<Person>>() { @Override protected List<Person> call() throws Exception { return mgrModel.loadAllPersons(); } }; loadPersonAsGUIComponentsTask.setOnSucceeded(e -> { if (loadPersonAsGUIComponentsTask.getValue() != null) { List<Person> allPersons = loadPersonAsGUIComponentsTask.getValue(); Task<Boolean> updateGUITask = new Task<Boolean>() { @Override protected Boolean call() throws Exception { // mgrModel.setAllPersonsPlain(allPersons); List<Node> list = mgrModel.getAllPersonNodes(); list.clear(); allPersons.stream().parallel().forEach(n -> { try { list.add(getNodeForVolunteer(n)); } catch (IOException ex) { ex.printStackTrace(); } }); mgrModel.setAllPersons(list); // for (Person personsToLoadInAsNode : allPersons) // { // try // { // mgrModel.getAllPersonNodes().add(getNodeForVolunteer(personsToLoadInAsNode)); // } catch (IOException ex) // { // ex.printStackTrace(); // } // } return true; } }; updateGUITask.setOnSucceeded(j -> { Task<Void> anotherTask = new Task<Void>() { @Override protected Void call() throws Exception { // Platform.runLater(() -> { mainBorderPane.setCenter(null); mainBorderPane.setCenter(centerNode); //Clears loading icon here masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes()); } ); return null; } }; anotherTask.setOnSucceeded(o -> { txtFieldSearch.setVisible(true); btnShowSidePanel.setVisible(true); comboBoxNewLocation.setVisible(true); btnDeleteSavedLocation.setVisible(true); // btnBackMan.setVisible(true); Platform.runLater(() -> { scrollPane.requestFocus(); }); scrollPane.requestLayout(); masonryPane.requestLayout(); }); execService.execute(anotherTask); // System.out.println("done"); // System.out.println("here"); // masonryPane.getChildren().setAll(mgrModel.getAllPersonNodes()); // scrollPane.requestLayout(); }); execService.execute(updateGUITask); } }); execService.execute(loadPersonAsGUIComponentsTask); } /** * Closes the side panel. * * @param observable * @param oldValue * @param newValue */ @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (!newValue) { stackPane.getChildren().remove(slide); mainBorderPane.getCenter().setEffect(null); } } /** * Filters the volunteers shown in the masonrypane * * @param event */ @FXML private void searchAction(KeyEvent event) { String newValue = txtFieldSearch.getText(); if (!newValue.equals(oldValue)) { List<Node> filteredList = mgrModel.filterList(newValue); masonryPane.getChildren().setAll(filteredList); } oldValue = txtFieldSearch.getText(); } /** * Go back man * * @param event */ private void handleGoBack(ActionEvent event) { VolunteerModel vmodel = VolunteerModel.getInstance(); // mgrModel.setRightSideNode(null); // mgrModel.getAllPersonNodes().clear(); // mgrModel.setCurrentToggle(10); // mgrModel.setAllPersons(null); Stage mainView = (Stage) scrollPane.getScene().getWindow(); snackBar.close(); undoSnackbar.close(); mainView.close(); Parent mainViewLoad = null; try { ResourceBundle bundle = ResourceBundle.getBundle("mytime.gui.UIResources", vmodel.getLocale()); mainViewLoad = FXMLLoader.load(getClass().getResource("/mytime/gui/view/LoginMainView.fxml"), bundle); } catch (IOException ex) { Logger.getLogger(LoginOneVolunteerController.class.getName()).log(Level.SEVERE, null, ex); } Scene scene = new Scene(mainViewLoad); mainView.setScene(scene); mainView.setResizable(true); mainView.show(); } @FXML private void handleDeleteSavedLocation(ActionEvent event) { try { snackBar.show(" Slettede 'husk denne lokation's-indstilling på denne computer. \n Brugeren skal vælge en ny lokation næste gang programmet starter.", 7500); comboBoxNewLocation.getSelectionModel().clearSelection(); mgrModel.clearSavedLocationInFile(); } catch (IOException ex) { ex.printStackTrace(); } } }