Skip to content

Instantly share code, notes, and snippets.

@jsamr
Last active November 1, 2016 05:27
Show Gist options
  • Save jsamr/87022078906a3710fc33f25c399f7f3a to your computer and use it in GitHub Desktop.
Save jsamr/87022078906a3710fc33f25c399f7f3a to your computer and use it in GitHub Desktop.
 v 1.1.0

 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 |||                                                                           |||
 !!! MERCI DE LIRE ATTENTIVEMENT CE DOCUMENT AVANT DE COMMENCER LE LABORATOIRE !!!
 |||                                                                           |||
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||


 Le fichier markdown README.MD est un incontournable.
 N'importe quel projet doit en comporter un pour donner les informations 
 importantes aux nouveaux collaborateurs.
 
 L'IDE recommandée pour ce projet est INTELLIJ IDEA 2016 ou supérieur.
 ECLIPSE peut être utilisé, mais il offre beaucoup moins de fonctionnalités.
 C'est un peu comme comparer une Tesla S à une deux chevaux, les deux nous 
 permettent d'avancer, mais pas à la même vitesse.

 -- dans INTELLIJ IDEA, cliquez sur l'icône en haut à droite de l'éditeur  
    pour afficher la version HTML de ce document (show preview only).
    Vous devez avec le plugin « Markdown support » d'installé.
 
 -- vous pouvez sinon consulter la version HTML à cette adresse : 
    https://goo.gl/yeKZ7f




STUDYZ

Présentation de l'organisation des sources et de l'architecture du programme.

packages

package description
ca.usherbrooke.ift215.studyz Coeur de l'application, c'est ici que vous allez implémenter les écrans.
ca.usherbrooke.ift215.studyz.control Définition des contrôleurs propres à chaque composant implémenté.
ca.usherbrooke.ift215.studyz.model Description des données métier.
ca.usherbrooke.ift215.studyz.view Description de l'arborescence des vues propre à chaque composant, dans des fichier FXML.
ca.usherbrooke.ift215.fx Mini-librairie offrant un cadre architectural à l'application.
ca.usherbrooke.ift215.fx.act Utilitaire pour gérer des événements haut-niveau, appelés intents.

Arborescence des composants

La racine de l'arbre est le composant Studyz, qui hérite de BorderPane.
Lorsque l'étudiant n'est pas authentifié, le composant Authenticator est affiché.
Lorsque l'étudiant est authentifié, c'est le composant PagesContainer qui est affiché.
Vous n'avez pas à implémenter ce comportement.

       |-- top : Header                                             |-- StudentProfileReadView
       |                                                            |           (ou)
Studyz |     (et)                         |-- StudentProfilePage -- |-- StudentProfileEditView
       |            |-- Authenticator     |                         |           (ou)
       |-- center : |        (ou)         |                         |-- StudentProfilePassEditView
                    |-- PagesContainer -- |         (ou)
                                          |                         |-- StudentCoursesReadView
                                          |-- StudentCoursesPage -- |           (ou)
                                                                    |-- StudentCoursesEditView

On remarquera qu'au troisième niveau on a des "pages", et au quatrième des "vues". Ce vocabulaire est propre à cette architecture et n'est pas générique. Je vous recommande cependant de l'adopter, c'est une représentation qui vient du web et que vous devriez comprendre intuitivement.
Une page est un composant qui occupe une majeure partie de la scène, et dont chaque vue porte sur un même objet. L'utilisateur peut basculer d'une page à l'autre à l'aide du menu en tête de scène. On a donc différentes vues pour une même page.

Dépendances (maven)

Dans le fichier pom.xml sont définies les librairies dont dépend le projet.

espace de nom documentation générale description
de.jensd.fontawesomefx fontawesomefx Librairie permettant l'affichage d'icônes issues de polices d'icônes parmi les plus populaires du web (fontawesome, materialdesign, materialicons, ...).
org.fxmisc.easybind easybind Librairie simple et puissante qui améliore l'api Fluent de Javafx (Bindings) à l'aide de lambdas.
org.controlsfx controlsfx Librairie de composants javafx, riche et très bien documentée.

Ci dessous, des cas d'utilisation pour chaque librairie dont vous aurez besoin.

Fontawesomefx

Cette librairie est nécessaire pour les laboratoire 4 & 5
Elle est importée automatiquement par Maven

    <Button text="ANNULER" onAction="#handleCancel">
        <graphic>
            <MaterialDesignIconView glyphName="CLOSE_CIRCLE" size="24"/>
        </graphic>
    </Button>

Pour voir les icônes disponibles avec MaterialDesignIconView, se rendre à cette adresse.

Easybind

Cette librairie est nécessaire pour les laboratoire 4 & 5
Elle est importée automatiquement par Maven

    MonadicObservableValue<Teacher> teacherMonadicValue = EasyBind.monadic(teacherProperty);
    salaryLabel.textProperty().bind(teacherMonadicValue.selectProperty(Teacher::salaryProperty));

On attache la propriété de texte du salaryLabel de type Label à la propriété 'salary' de l'enseignant.
Deux grands avantages :

  • Cette liaison est 'null safe' : si la valeur enveloppée par teacherProperty vaut null, le String enveloppé par la propriétée de texte du Label vaudra null, sans qu'une exception soit levée.
  • Cette liaison est 'type safe' face à son équivalent avec Bindings, confère cet exemple.
    MonadicObservableValue<Teacher> teacherMonadicValue = EasyBind.monadic(teacherProperty);
    uniqueIdentifierLabel.textProperty().bind(teacherMonadicValue.map(Teacher::getUniqueIdentifier))

On attache la propriété de texte du uniqueIdentifierLabel de type Label à la valeur 'uniqueIdentifier' de l'enseignant. (ligne 3)
Cet exemple ressemble à s'y méprendre au précédent, à la différence près que le champs de l'enseignant n'est pas une propriété (StringProperty ou ObjectProperty<Srting>), mais un simple String.

CSS

Cette section est notamment utile pour le laboratoire 3

L'apparence d'un composant peut être contrôlée par sa classe de style. En FXML, c'est l'attribut styleClass qui permet de le définir.
C'est une très bonne pratique que de séparer l'apparence des composants et leur arborescence.
Dans ce laboratoire, vous n'avez pas à implémenter l'apparence des composants, mais simplement de leur donner la bonne classe de style qui est déjà définie dans src/ca/usherbrooke/ift215/studyz/view/base.css.

Voici un exemple avec la barre de boutons qui apparaît en bas de chaque vue :

<FlowPane styleClass="intents" alignment="CENTER">
    <ButtonBar>
        <buttons>
            <Button  text="CUISINER UN COOKIE"
                    onAction="#handleCookCookie">
                <graphic>
                    <MaterialDesignIconView glyphName="COOKIE" size="24"/>
                </graphic>
            </Button>
        </buttons>   
    </ButtonBar>
</FlowPane>            

On applique la classe de style intents pour que l'apparence de la barre de boutons soit la même entre chaque vue.

REMARQUE : Pour appliquer plusieurs styles, il faut les séparer par des virgules.

Modèle événementiel

Cette section est notamment utile pour les laboratoire 4 & 5

Lorsqu'un utilisateur clique sur un bouton, il s'attend à voir la vue s'adapter pour rendre compte de son intent.

Méthode naïve

En JavaFX, on va définir une méthode dans le contrôleur, par exemple :

// MyComponent.java
    
    public void handleOpenMyTasks() {
        this.pagesHandler.openTasks();
    }
    

Cette méthode a besoin d'une référence au composant qui va ouvrir la page de taches, ici pagesHandler.

On va référencer cette méthode dans le composant Button de la vue :

<!-- MyComponent.fxml -->

    <Button onAction="#handleOpenMyTasks" />
    

Problème : on a besoin de la référence du composant sur lequel appliquer l'intent (changer de page, afficher un dialogue, ...etc), ici pagesHandler. À mesure que l'application se complexifie, chaque composant comporte un grand nombre de références à d'autres composants. C'est ce qu'on appelle un couplage fort et c'est le signe d'une mauvaise qualité de code.

Il existe même une expression consacrée en programmation, le code spaghetti !

Solution : un moteur d'événements haut-niveau

Un moteur d'événements haut-niveau - c'est à dire proche du langage naturel - permet la diffusions d'actions de l'utilisateur en vue d'un but. Deux actions distinctes (clic sur un bouton, appuis sur une touche) peuvent avoir le même résultat, comme le chargement d'une interface.

Exemple : L'utilisateur clique sur CTRL + MAJ + R dans Intellij Idea pour remplacer un mot dans l'ensemble du dossier sélectionné, ou bien fait EditFindReplace in Path.
L'issue - l'ouverture d'une boîte de dialogue - est la même, mais l'action diffère. C'est pourquoi on va parler pour la suite d'intention (intent). C'est un niveau d'abstraction supplémentaire qui permet de simplifier l'architecture globale de l'application.

Le package ca.usherbrooke.ift215.fx.act expose une API pour gérer facilement les actions de haut-niveau, appelées "intentions" de l'utilisateur.
Pour Studyz, les intentions sont définies dans l'énumération ca.usherbrooke.ift215.studyz.StudyzIntent.

Reprenons l'exemple précédent, mais cette fois-ci utilisons le moteur d'événements pour ouvrir la page :

// MyComponent.java
    
    public void handleOpenMyTasks() {
        this.intentEngine.dispatch(StudyzIntent.READ_TASKS);
    }
    

Mon composant n'a maintenant besoin que d'une seule référence à un IntentEngine, plus de spaghetti !

Voici à quoi ressemble le code du composant qui va afficher les tâches :

// MyParentComponent.java
    
    public MyComponentParent(IntentEngine intentEngine) {
        // à chaque fois que l'événement READ_TASKS est propagé, displayTasks sera appelé.
        intentEngine.subscribe(SomeIntent.READ_TASKS, this::displayTasks);
    }
    
    public void displayTasks() {
        // du code interne au composant pour afficher les tâches
    }
    

Dans le fichier FXML, rien ne change :

<!-- MyComponent.fxml -->

    <Button onAction="#handleOpenMyTasks" />
    

Il existe des mécanismes plus élaborés, populaires dans certains frameworks du web comme redux, qui ne sont pas à la portée de ce cours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment