Java tutorial
/* * 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 mesclasses.view; import com.google.common.eventbus.Subscribe; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import javafx.animation.FadeTransition; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.util.Duration; import mesclasses.controller.PageController; import mesclasses.handlers.EventBusHandler; import mesclasses.handlers.ModelHandler; import mesclasses.handlers.PropertiesCache; import mesclasses.model.Constants; import mesclasses.model.FileConfigurationManager; import mesclasses.model.datamodel.ObservableData; import mesclasses.objects.Screen; import mesclasses.objects.events.ChangeEvent; import mesclasses.objects.events.IsAliveEvent; import mesclasses.objects.events.MessageEvent; import mesclasses.objects.events.OpenMenuEvent; import mesclasses.util.AppLogger; import mesclasses.util.CssUtil; import mesclasses.util.DataLoadUtil; import mesclasses.util.EleveFileUtil; import mesclasses.util.FileSaveUtil; import mesclasses.util.ModalUtil; import mesclasses.util.validation.FError; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * * @author rrrt3491 */ public class RootLayoutController extends PageController implements Initializable { private static final Logger LOG = LogManager.getLogger(RootLayoutController.class); @FXML private BorderPane mainPane; @FXML private StackPane notificationPane; @FXML private Button deleteNotifBtn; @FXML private Label notificationTitleLabel; @FXML private Label notificationMessageLabel; private PageController currentController; private String currentView; private Map<String, Screen> screenMap; private boolean saveNeeded; @FXML public void openAccueil(ActionEvent event) { loadView(Constants.ACCUEIL_VIEW); } @FXML public void openAdminTrimestre(ActionEvent event) { loadView(Constants.ADMIN_TRIMESTRE_VIEW); } @FXML public void openAdminClasse(ActionEvent event) { loadView(Constants.ADMIN_CLASSE_VIEW); } @FXML public void openAdminEleve(ActionEvent event) { loadView(Constants.ADMIN_ELEVE_VIEW); } @FXML public void openTimetable(ActionEvent event) { loadView(Constants.EMPLOI_DU_TEMPS_VIEW); } @FXML public void openJournees(ActionEvent event) { loadView(Constants.JOURNEE_VIEW); } @FXML public void openRapports(ActionEvent event) { loadView(Constants.CLASSE_RAPPORT_TABS_VIEW); } @FXML public void openHistorique(ActionEvent event) { loadView(Constants.HISTORIQUE_VIEW); } @FXML public void openConfiguration(ActionEvent event) { loadView(Constants.CONFIGURATION_VIEW); } @Subscribe public void openMenu(OpenMenuEvent event) { logEvent(event); if (loadView(event.getView())) { currentController.setPreviousPage(event.getFromView()); } } @Subscribe public void detectChange(ChangeEvent event) { logEvent(event); primaryStage.setTitle(Constants.APPLICATION_TITLE + " * version " + PropertiesCache.version()); saveNeeded = true; } @Override public void setPrimaryStage(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setOnCloseRequest(ev -> { ev.consume(); handleExit(); }); } private boolean loadView(String view) { try { if (currentController != null) { if (!currentController.notifyExit()) { return false; } } LOG.info("Loading view " + view); currentView = view; // la page a dj t charge une fois, donc on doit rafraichir le controller boolean reload = screenMap.containsKey(view); Screen screen = getScreen(view); if (screen == null || screen.getCtrl() == null) { LOG.error("screen is null"); return false; } mainPane.setCenter(screen.getRoot()); currentController = screen.getCtrl(); if (reload) { LOG.debug("Reloading controller"); currentController.reload(); return true; } return true; } catch (Exception e) { notif(e); return false; } } private Screen getScreen(String view) { Screen screen = screenMap.get(view); if (screen == null) { screen = new Screen(view, primaryStage); screenMap.put(view, screen); } return screen; } /** * Saves the data */ @FXML public void handleSave() { if (currentController != null && !currentController.notifySave()) { return; } if (save()) { EventBusHandler.post(MessageEvent.success("Donnes sauvegardes")); model.getData().resetChange(); primaryStage.setTitle(Constants.APPLICATION_TITLE); saveNeeded = false; if (currentController != null) { currentController.reload(); } } } private boolean save() { model.cleanupClasses(); model.cleanUpJournees(); List<FError> err = model.getData().validate(); if (err.isEmpty() || ModalUtil.confirm("Donnes incohrentes", "Sauvegarder quand mme ?")) { return DataLoadUtil.writeData(model.getData(), FileSaveUtil.getSaveFile()); } return false; } @FXML public void handleLoad() { FileChooser chooser = new FileChooser(); chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Fichiers de sauvegarde", "*.xml")); chooser.setTitle("Slectionnez un fichier de sauvegarde"); chooser.setInitialDirectory(new File(FileConfigurationManager.getInstance().getBackupDir())); File file = chooser.showOpenDialog(primaryStage); if (file == null) { return; } if (DataLoadUtil.isfileEmpty(file)) { ModalUtil.alert("Impossible de lire les donnes du fichier", "Ce fichier est vide"); return; } ObservableData data; try { data = DataLoadUtil.initializeData(file); } catch (Exception e) { ModalUtil.alert("Impossible de lire les donnes du fichier", "Ce fichier n'est pas un fichier de sauvegarde " + Constants.APPLICATION_TITLE + " valide"); return; } if (ModalUtil.confirm("Charger le fichier " + file.getName(), "Les donnes actuelles seront perdues")) { FileSaveUtil.restoreBackupFile(file); loadData(data); } } @Subscribe public void onMessage(MessageEvent event) { displayNotification(event.getType(), event.getMessage()); } private void displayNotification(int type, String texte) { notificationMessageLabel.setText(texte); notificationPane.getStyleClass().clear(); CssUtil.removeClass(deleteNotifBtn, "notif-warning"); CssUtil.removeClass(deleteNotifBtn, "notif-error"); Double timeDisplayed = 3.0D; switch (type) { case MessageEvent.SUCCESS: CssUtil.addClass(notificationPane, "notif-success"); deleteNotifBtn.setManaged(false); deleteNotifBtn.setVisible(false); notificationTitleLabel.setText("SUCCES"); break; case MessageEvent.WARNING: CssUtil.addClass(notificationPane, "notif-warning"); CssUtil.addClass(deleteNotifBtn, "notif-warning"); notificationTitleLabel.setText("ATTENTION"); break; case MessageEvent.ERROR: CssUtil.addClass(notificationPane, "notif-error"); CssUtil.addClass(deleteNotifBtn, "notif-error"); notificationTitleLabel.setText("ERREUR"); timeDisplayed = 0.0; break; } notificationPane.setManaged(true); notificationPane.setVisible(true); if (timeDisplayed > 0.0) { FadeTransition ft = new FadeTransition(Duration.millis(150), notificationPane); ft.setFromValue(0.0); ft.setToValue(1.0); ft.setCycleCount(1); ft.play(); Timeline timeline = new Timeline(); timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(timeDisplayed), (ActionEvent event) -> { FadeTransition ft2 = new FadeTransition(Duration.millis(150), notificationPane); ft2.setFromValue(1.0); ft2.setToValue(0.0); ft2.setCycleCount(1); ft2.play(); ft2.setOnFinished((ActionEvent event1) -> { notificationPane.setManaged(false); notificationPane.setVisible(false); }); })); timeline.play(); } } @FXML public void closeNotif() { notificationPane.setManaged(false); notificationPane.setVisible(false); } @FXML private void handleExit() { if (canExit()) { AppLogger.logExit(RootLayoutController.class); System.exit(0); } } private boolean canExit() { if (saveNeeded) { String res = ModalUtil.yesNoCancel("Des modifications n'ont pas t sauvegardes", "Voulez-vous sauvegarder avant de quitter ?"); if ("cancel".equals(res)) { return false; } if ("yes".equals(res)) { try { handleSave(); } catch (Exception e) { notif(e); return false; } } } return true; } @Override public void initialize(URL location, ResourceBundle resources) { name = "Root Layout Ctrl"; super.initialize(location, resources); notificationPane.setManaged(false); notificationPane.setVisible(false); notificationPane.setOnMouseClicked((MouseEvent mouseEvent) -> { if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) { closeNotif(); } }); screenMap = new HashMap<>(); loadData(null); } private void loadData(ObservableData data) { if (data != null) { ModelHandler.getInstance().injectData(data); data.startChangeDetection(); } screenMap.values().forEach(screen -> { screen.stop(); }); screenMap.clear(); openAccueil(null); } @Override public boolean notifyExit() { return true; } @FXML public void onReset() { if (ModalUtil.confirm("Rinitialisation des donnes", "Etes-vous sr(e) ?")) { try { FileSaveUtil.archive(); EleveFileUtil.purge(); } catch (IOException e) { notif(e); return; } loadData(new ObservableData()); save(); } } @FXML public void onExport() { File archive; try { archive = FileSaveUtil.archive(); } catch (IOException e) { notif(e); return; } FileChooser chooser = new FileChooser(); chooser.setTitle("Sauvegardez les donnes"); chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Archive MesClasses", "*.zip")); LOG.info("archiving in " + archive.getPath()); chooser.setInitialFileName(FilenameUtils.getName(archive.getPath())); File file = chooser.showSaveDialog(primaryStage); if (file != null) { try { FileUtils.moveFile(archive, file); } catch (IOException ex) { notif(ex); } displayNotification(MessageEvent.SUCCESS, "Donnes sauvegardes"); } } @FXML public void onImport() { if (ModalUtil.confirm("Importer des donnes", "Cette opration crasera les donnes existantes.\nEtes-vous sr(e) ?")) { FileChooser chooser = new FileChooser(); chooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Archive MesClasses", "*.zip")); chooser.setTitle("Slectionnez une archive"); chooser.setInitialDirectory(new File(FileConfigurationManager.getInstance().getArchivesDir())); File file = chooser.showOpenDialog(primaryStage); if (file == null) { return; } try { FileSaveUtil.restoreArchive(file); } catch (IOException e) { notif(e); return; } try { ObservableData data = DataLoadUtil.initializeData(FileSaveUtil.getSaveFile()); loadData(data); } catch (Exception e) { notif(e); } } } @FXML public void isAlive() { EventBusHandler.post(new IsAliveEvent()); } }