1.25k likes | 1.52k Views
Cédric Dumas Jean-Daniel Fekete Ecole des Mines de Nantes. Conception d’IHM en Java. Cedric.Dumas@emn.fr contrat Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique 2.0 France License. Concepts Généraux. Conception d’IHM en Java.
E N D
Cédric Dumas Jean-Daniel Fekete Ecole des Mines de Nantes Conception d’IHM en Java Cedric.Dumas@emn.frcontrat Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique 2.0 France License
Concepts Généraux Conception d’IHM en Java
Java et les interfaces graphiques interactives Langage conçu d'emblée avec une interface graphique interactive Ajout de mécanismes spécifiques pour les interfaces inner classes 2 interfaces et 2 modèles graphiques en standard Beaucoup d'exemples, de documentations et d'expérience.
Application graphique interactive : architecture Les boîtes à outils 2D sont maintenant très stéréotypées 3 composants système de fenêtrage API graphique gestion de l'arbre d'affichage et d'interaction Organisation sous forme d'objets
Le système de fenêtrage Accès partagé à l'écran Subdivision de l'écran en fenêtres Chaque fenêtre est positionné (x, y, z) et dimensionnée (largeur x hauteur) Modèle graphique d'affichage Modèle d'événements Communication entre les applications Gestion de ressources spécifiques
Les API graphiques Dans une fenêtre, une application dessine en utilisant des fonctions qui prennent des paramètres 2 catégories en 2D orientée pixel orientée "dimension réelle", ou "indépendante de la résolution" Richesse variable suivant les plate formes
La gestion de l'arbre d'affichage Afficher = appeler une succession de fonctions graphiques Représentation sous forme d'un arbre d'affichage (ou graphe directe acyclique) On affiche récursivement, en profondeur d'abord, tous les nœuds de l'arbre On modifie l'arbre pour changer l'affichage puis on réaffiche
La gestion de l'interaction Les dispositifs d'entrée génèrent des événements (petit bloc mémoire contenant un type, un temps, une fenêtre cible et des détails suivant le type) La boîte à outils achemine l'événement vers un nœud cible Le nœud gère l'événement, ce qui peut modifier l'état de l'arbre d'affichage On passe à l'événement suivant
Acheminement des événements Positionnel (souris) on regarde quel est le nœud de l'arbre le plus près de la position On l'envoie au plus prés, qui renvoie a son père s'il ne veut pas le gérer Non positionnel (clavier) si un nœud à le "focus", on lui envoie traduction d'une touche en caractère(s) ou action sinon, on cherche une cible gestion des raccourcis clavier
Les composants graphiques interactifs Le nœud est capable de s'afficher et de gérer les événement On lui ajoute une interface de communication suivant sa sémantique bouton, label, menu, ligne de texte, etc. On appelle ce nœud communicant un composant ou widget ou gadget ou objet de contrôle.
Organisation sous forme d'objets Les langages à objets permettent de représenter ces nœuds comme des objets ayant une interface Tous les nœuds héritent d'une classe de base (Component dans Java) Chaque composant particulier spécifie une interface particulière adaptée à sa sémantique
Principales différences entre les GUIs Il existe un grand nombre de boîtes à outils graphiques interactives (Graphical User Interfaces ou GUI) Langage / portabilité / performances / mécanismes de communications / extensibilité / rapidité de développement / robustesse Pas de "meilleur" mais des spécialisations Lire le chapitre consacré aux GUIs
Les boîtes à outils graphiques interactives de Java Java propose deux boîtes à outils graphiques : AWT (Abstract Window Toolkit), simple, petite et limitée SWING, cohérente, grosse et extensible. Les deux peuvent s'utiliser dans les applets SWING facilite la transition à partir d'AWT.
AWT Conception d’IHM en Java
Java AWT Interface indépendante de la plate-forme API simple (simpliste) Composants peu nombreux Apparence pauvre Relativement rapide Similaire sur toutes les plate-formes
Organisation d ’AWT Packages java.awt et java.applet Classes de composants (dérivées de Component) Composants conteneurs Composants « feuille » Classes de gestionnaire d’événements Myriade de classes utilitaires Image, Color, Cursor, Dimension, Font, etc.
SWING Conception d’IHM en Java
Java SWING SWING implémente tous les composants en Java SWING offre plusieurs mécanismes originaux, pratiques et puissants SWING peut se programmer à plusieurs niveaux SWING est très gros et souvent lent.
Programmation avec Java SWING Généralités sur Java SWING SWING et AWT Concepts de SWING Une application Java SWING pas à pas TPs Les composants standards de SWING Créer ses propres composants
SWING et AWT SWING cohabite avec AWT et utilise le minimum de ses services Tous les composants sont redéfinis AWT n ’est pas régulier pas de canvas dans un menu SWING est totalement régulier tout conteneur peut afficher tout objet graphique
Concepts de SWING Séparation du composant et de son apparence plusieurs apparences existent: Windows, Unix, Mac et « Metal » L ’apparence par défaut dépend de la plate forme Séparation du composant et de son modèle Séparation du composant et de son modèle de sélection
Concepts de SWING Basé sur des containers générique gère collection de composants design Pattern composite
Programmation SWING Package javax.swing Relativement proche de AWT pour faciliter la migration, ajout « J » avant le nom des classes:
Construction d ’une application Construire un arbre d ’objets dérivés de « JComponent » Attacher des gestionnaires d ’événements Ce sont les gestionnaires d ’événements qui feront les actions et modifieront les composants
Exemple import java.awt.*; import javax.swing.*; class hwSwing { public static void main(String args[]) { JFrame f = new JFrame("Hello World"); Jlabel texte = new JLabel("Hello World"); f.getContentPane().add(texte); f.pack(); f.setVisible(true); } }
Autre approche import java.awt.*; import javax.swing.*; public class Test { public static void main(String args[]) { Simple f = new Simple(); f.pack(); f.setVisible(true); } } public class Simple extends JFrame { Jlabel texte = new JLabel("Hello World"); public Simple() { getContentPane().add(texte); } }
explications Création de l ’arbre de composants : JFrame + JLabel ou JButton Déclaration des actions: addEventHandler + création d ’une « inner class » Calcul du placement des composants: pack Affichage
Mon premier Composant JFrame fenêtre principale JDialog fenêtre de dialogue (modale) Jwindow show() hide() ou dispose() toFront() ou toBack() setTitle(“titre !”) setSize(int, int) et setResizable(false)
Jlabel Javax.swing.Jlabel descriptif : texte statique + image exemple : devant un champ de saisie Jlabel jl = new Jlavel(“Label 1”); ou jl.setText(“Label 1”); // -> .getText() jl.setIcon(new ImageIcon(“java.gif”)); jl.setVerticalTextPosition(SwingConstants.BOTTOM) jl.setHorizontalTextPosition(SwingConstants.CENTER);
JTextField Javax.swing.JTextField saisie de texte (non typé) JTextField jt = new JTextField(“Thomas”); String nom = new String(“Thomas”); jt.setText(nom); jt.setColumns(nom.length()); jt.copy(); jt.cut(); jt.paste();
JButton Bouton simple à états JButton jb= new Jbutton(“OK”,new ImageIcon(“boc.gif)); jb.setRolloverIcon(new ImageIcon(“cob.gif”)); jb.setPressedIcon(new ImageIcon(“ocb.gif”)); jb.setDisabledIcon(new ImageIcon(“obc.gif”)); jb.setMnemonic(‘o’); // ALT + o jb.setBorderPainted(false); jb.setFocusPainted(false); jb.doClick();
JmachinButton JToggleButton deux états (setIcon et setSelectedIcon) JCheckBox cases à cocher JRadioButton dans un groupe de bouttons “radio” penser à regarder Abstract Button
Exemple de Radio ButtonGroup grp = new ButtonGroup(); JRadioButton r1 = new JRadioButton(“it1”); JRadioButton r2 = new JRadioButton(“it2”); r2.setSelected(true); grp.add(r1); grp.add(r2);
Le modèle de bouton poussoir Modèle utilisé pour les CheckBox, RadioButton et Button Plusieurs niveaux d ’utilisation gère l ’état du bouton, au repos, sous le pointeur, appuyé et relâché. Gère la notification vers les listeners Gère l ’envoie d ’un événement « action »
Le modèle de bouton poussoir (2) public interface ButtonModel extends ItemSelectable { attribute boolean armed; attribute boolean selected; attribute boolean enabled; attribute boolean pressed; attribute boolean rollover; attribute int mnemonic; attribute String actionCommand; attribute ButtonGroup group; listener ActionListener; listener ItemListener; listener ChangeListener; }
JComboBox Liste déroulante (ouverte ou fermée) vector ou tableau d’objets passés en paramètres JComboBox cb = new JComboBox( items); cb.setMaximumRowCount(4); cb.setEditable(true); // JTextField
JMenu Une instance de JMenuBar par Jframe setJMenuBar(JMenuBar mb); Plusieurs Jmenu par JMenuBar add(JMenu jm); Plusieurs JMenuItem/JCheckboxMenu par Jmenu add(JMenuItem mi); addSeparator(); Structurez !!!
JPanel Jpanel conteneur JScrollPane un seul composant ! barres de défilement JScrollPane sp = new JScrollPane(); sp.add(monJLabel); sp.setViewportView (monJLabel); composants implémentant Scrollable class MonLabel extends Jlabel implements Scrollable Panel ScrollPane
Les composants de SWING Dialog Frame Tabbed Pane Split pane Tool bar Internal frame Layered pane
Composants de Swing List Tool tip File chooser Color chooser Progress bar Slider Table Text Tree
Capacités communes des composants (dés)activation isEnabled() setEnabled(…) (in)visible setVisible(…) isVisible() module le coût de l’instanciation d’un container ! tailles réelle et souhaitable Dimension getSize() ou Dimension getSize(Dimension r) setSize(…) Dimension getPreferredSize() ; setPreferredSize(Dimension r);
Factory Bordures Border mbd= new Border( BorderFactory.createEtchedBorder() BorderFactory.createLoweredBevelBorder() BorderFactory.createTitledBorder(“Titre !”) etc… ); monJbutton.setBorder(mbd); Curseur Cursor nc = new Cursor(Cursor.CROSSHAIR_CURSOR); monJbutton.setCursor(nc);
Couleurs new Color (r,g,b) new Color (r,g,b,a) 0 -> 255 a=255 opaque monJbutton.setBackground(Color.white); //constantes monJbutton.setForeground(Color.black); monJbutton.setOpaque(true);
Quelques difficultés à retenir Conteneurs de fenêtre : ne pas ajouter directement avec "add" mais ajouter avec "getContentPane()" Pas de multi-threading, sauf autorisation explicite dans la documentation
Pourquoi getContentPane ? Les containers Swing ont un JRootPane monContainer.getContentPane().add(...) composants « lourds » : JDialog, JFrame, JWindow Root pane
La classe JComponent Tool tip Bords Actions associées aux touches Propriétés Accès aux handicapés Double buffer
Swing : la gestion du placement des composants Conception d’IHM en Java
Calcul du placement Le placement est calculé dans les conteneurs Soit les composants sont placés explicitement (x, y, largeur, hauteur) Soit ils sont gérés par un « LayoutManager » qui calcul ces paramètres dynamiquement besoins du composant (taille min, max, normale) + positionnement relatif
Mise en place d ’un gestionnaire de placement Les conteneurs définissent la méthode setLayout(layoutManager) pour changer le gestionnaire par défaut Le gestionnaire par défaut change d ’une classe de conteneur à une autre La méthode pack() déclenche le calcul du placement La méthode invalidate() rend le placement courant invalide