Java tutorial
package mesclasses.view; /* * 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. */ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.eventbus.Subscribe; import java.io.IOException; import java.net.URL; import java.util.List; import java.util.ResourceBundle; import java.util.stream.Collectors; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.stage.Modality; import javafx.stage.Stage; import mesclasses.MainApp; import mesclasses.controller.PageController; import mesclasses.model.Constants; import mesclasses.model.Cours; import mesclasses.objects.events.CreateCoursEvent; import mesclasses.util.CssUtil; import mesclasses.util.ModalUtil; import mesclasses.util.NodeUtil; import org.apache.commons.lang3.StringUtils; /** * FXML Controller class * * @author rrrt3491 */ public class TimetableController extends PageController implements Initializable { @FXML AnchorPane anchor; @FXML Pane mondayPane; @FXML Pane tuesdayPane; @FXML Pane wednesdayPane; @FXML Pane thursdayPane; @FXML Pane fridayPane; @FXML Pane saturdayPane; @FXML Button newCoursBtn; @FXML ScrollPane scroll; private BiMap<String, Pane> paneMap = HashBiMap.create(); /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { // TODO name = "timetable ctrl"; super.initialize(url, rb); paneMap.put(Constants.DAYS.get(0), mondayPane); paneMap.put(Constants.DAYS.get(1), tuesdayPane); paneMap.put(Constants.DAYS.get(2), wednesdayPane); paneMap.put(Constants.DAYS.get(3), thursdayPane); paneMap.put(Constants.DAYS.get(4), fridayPane); paneMap.put(Constants.DAYS.get(5), saturdayPane); handleKeys(); handleClicks(mondayPane); handleClicks(tuesdayPane); handleClicks(wednesdayPane); handleClicks(thursdayPane); handleClicks(fridayPane); handleClicks(saturdayPane); newCoursBtn.setText("\uf067"); CssUtil.addClass(newCoursBtn, "button-ok"); cours.forEach(c -> { createEvent(c); }); cours.forEach(c -> { resizeEvent(c); getPane(c).getChildren().add(c.getEvent()); }); } private void handleKeys() { anchor.setOnKeyReleased((ev) -> { if (null != ev.getCode()) switch (ev.getCode()) { case ENTER: newCoursBtn.fire(); break; case UP: scroll.setVvalue(0); break; case DOWN: scroll.setVvalue(1.0); break; default: break; } ev.consume(); }); } private VBox createEvent(Cours theCours) { VBox event = new VBox(); CssUtil.addClass(event, "event"); CssUtil.addClass(event, getCSS(theCours)); String periodicite = theCours.getWeek().equals(config.getProperty(Constants.CONF_WEEK_DEFAULT)) ? "" : theCours.getWeek(); String salle = StringUtils.isNotBlank(theCours.getRoom()) ? "salle " + theCours.getRoom() : ""; Label periodiciteAndSalle = new Label((periodicite + " " + salle).trim()); bindWidth(periodiciteAndSalle, event, 1); Label classe = new Label(theCours.getClasse().getName()); CssUtil.addClass(classe, "event-classe"); bindWidth(classe, event, 1); //horaires HBox horaires = new HBox(); CssUtil.addClass(horaires, "horaires"); Label start = new Label(" " + NodeUtil.getStartTime(theCours)); CssUtil.addClass(start, "start"); Label end = new Label(NodeUtil.getEndTime(theCours) + " "); CssUtil.addClass(end, "end"); horaires.getChildren().add(start); horaires.getChildren().add(end); bindWidth(horaires, event, 1); bindWidth(start, horaires, 2); bindWidth(end, horaires, 2); event.getChildren().add(periodiciteAndSalle); bindHeight(periodiciteAndSalle, event, 3); event.getChildren().add(classe); bindHeight(classe, event, 3); event.getChildren().add(horaires); bindHeight(horaires, event, 3); event.setOnMouseReleased((e) -> { handleEditCours(theCours); }); theCours.setEvent(event); return event; } private String getCSS(Cours theCours) { return "event" + classes.indexOf(theCours.getClasse()) % 8; } private void bindWidth(Region node, Pane parent, int divider) { node.minWidthProperty().bind(parent.widthProperty().divide(divider)); node.prefWidthProperty().bind(parent.widthProperty().divide(divider)); node.maxWidthProperty().bind(parent.widthProperty().divide(divider)); } private void bindHeight(Region node, Pane parent, int divider) { node.minHeightProperty().bind(parent.heightProperty().divide(divider)); node.prefHeightProperty().bind(parent.heightProperty().divide(divider)); node.maxHeightProperty().bind(parent.heightProperty().divide(divider)); } private void resizeEvent(Cours cours) { VBox event = cours.getEvent(); Pane pane = getPane(cours); bindWidth(event, pane, 1); event.layoutXProperty().bind(pane.layoutXProperty()); Double startTime = cours.getStartHour() + cours.getStartMin() / 60.0; Double endTime = cours.getEndHour() + cours.getEndMin() / 60.0; Double height = Math.max((endTime - startTime) * 60, 20); event.layoutYProperty().bind(pane.layoutYProperty().add(60 * (startTime - 7))); event.setMinHeight(height); event.setPrefHeight(height); event.setMaxHeight(height); handleSimultaneousEvents(cours); } private void handleSimultaneousEvents(Cours cours) { List<Cours> liste = getSimultaneousCours(cours); Pane pane = getPane(cours); if (liste.size() == 1) { if (cours.getWeek().equals(config.getProperty(Constants.CONF_WEEK_P1_NAME)) || cours.getWeek().equals(config.getProperty(Constants.CONF_WEEK_P2_NAME))) { bindWidth(cours.getEvent(), pane, 2); } if (cours.getWeek().equals(config.getProperty(Constants.CONF_WEEK_P2_NAME))) { cours.getEvent().layoutXProperty().bind(pane.layoutXProperty().add(pane.widthProperty().divide(2))); } return; } for (int i = 0; i < liste.size(); i++) { VBox event = liste.get(i).getEvent(); event.layoutXProperty() .bind(pane.layoutXProperty().add(pane.widthProperty().multiply(i).divide(liste.size()))); bindWidth(event, pane, liste.size()); } } private List<Cours> getSimultaneousCours(Cours theCours) { List<Cours> liste = cours.stream().filter(c -> { return c.getDay().equals(theCours.getDay()) && Math.max(start(c), start(theCours)) < Math.min(end(c), end(theCours)); }).collect(Collectors.toList()); liste.sort((Cours t, Cours t1) -> { if (t.getWeek().equals(t1.getWeek())) { return classes.indexOf(t.getClasse()) - classes.indexOf(t1.getClasse()); } return t.getWeek().compareTo(t1.getWeek()); }); return liste; } private int start(Cours cours) { return cours.getStartHour() * 60 + cours.getStartMin(); } private int end(Cours cours) { return cours.getEndHour() * 60 + cours.getEndMin(); } @FXML public void handleNewCours() { Cours newCours = new Cours(); newCours.setClasse(classes.get(0)); newCours.setDay(Constants.DAYS.get(0)); newCours.setWeek(config.getProperty(Constants.CONF_WEEK_DEFAULT)); createNewCours(newCours); } private void createNewCours(Cours newCours) { newCours = openEditDialog(newCours, null); if (newCours != null) { model.createCours(newCours); VBox event = createEvent(newCours); resizeEvent(newCours); getPane(newCours).getChildren().add(event); } } @Subscribe public void createNewCoursFromEvent(CreateCoursEvent event) { logEvent(event); if (event.getClasse() != null) { Cours newCours = new Cours(); newCours.setClasse(classes.get(0)); newCours.setDay(Constants.DAYS.get(0)); newCours.setWeek(config.getProperty(Constants.CONF_WEEK_DEFAULT)); createNewCours(newCours); } } private void handleEditCours(Cours coursToEdit) { Cours editedCours = openEditDialog(model.cloneCours(coursToEdit), coursToEdit); if (editedCours != null) { getPane(coursToEdit).getChildren().remove(coursToEdit.getEvent()); model.updateCours(coursToEdit, editedCours); createEvent(editedCours); resizeEvent(editedCours); getPane(editedCours).getChildren().add(editedCours.getEvent()); } } private Pane getPane(Cours cours) { return paneMap.get(cours.getDay()); } private void handleClicks(Pane pane) { pane.setOnMouseClicked((MouseEvent mouseEvent) -> { if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) { if (mouseEvent.getClickCount() == 2) { Cours newCours = new Cours(); newCours.setClasse(classes.get(0)); newCours.setDay(paneMap.inverse().get(pane)); newCours.setWeek(config.getProperty(Constants.CONF_WEEK_DEFAULT)); newCours.setStartHour((int) (mouseEvent.getY()) / 60 + 7); newCours.setEndHour(newCours.getStartHour() + 1); createNewCours(newCours); } } }); } private Cours openEditDialog(Cours coursToEdit, Cours originalCours) { try { // Load the fxml file and create a new stage for the popup dialog. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource(Constants.COURS_EDIT_DIALOG)); AnchorPane page = (AnchorPane) loader.load(); // Create the dialog Stage. Stage dialogStage = new Stage(); dialogStage.setTitle("Edition d'un cours"); dialogStage.initModality(Modality.WINDOW_MODAL); dialogStage.initOwner(primaryStage); Scene scene = new Scene(page); dialogStage.setScene(scene); // Set the person into the controller. CoursEditDialogController controller = loader.getController(); controller.setDialogStage(dialogStage); controller.setCours(coursToEdit, false); // Show the dialog and wait until the user closes it dialogStage.showAndWait(); int status = controller.getStatus(); if (status >= 0) { //update/cancel return controller.getCours(); } else { //delete getPane(coursToEdit).getChildren().remove(coursToEdit.getEvent()); int seances = model.delete(originalCours).size(); ModalUtil.info("Sances modifies", seances + " sances ont t modifies"); return null; } } catch (IOException e) { notif(e); return null; } } }