Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Eclipse : Standard Widget Toolkit (SWT)

Eclipse : Standard Widget Toolkit (SWT)

Ce support de cours s'intéresse à présenter la boîte à outils SWT : évolution des boîtes à outils pour Java, conteneurs, composants de type Control, agents de placement, gestion des événements, Graphical Context, co-habitation entre SWT et Swing, traitement synchrone et asynchrone (ThreadUI) et les boîtes de dialogue.

Mickael BARON

February 25, 2013
Tweet

More Decks by Mickael BARON

Other Decks in Programming

Transcript

  1. Développement de clients riches : Plateforme Eclipse Mickaël BARON -

    2007 (Rév. Janvier 2009) mailto:[email protected] ou mailto:[email protected] mickael-baron.fr mickaelbaron (SWT) - Standard Widget Toolkit Chapitre 2 : Boîtes à outils
  2. 2 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Creative

    Commons Contrat Paternité Partage des Conditions Initiales à l'Identique 2.0 France http://creativecommons.org/licenses/by-sa/2.0/fr Licence
  3. 3 SWT - M. Baron - Page mickael-baron.fr mickaelbaron 3

    À propos de l’auteur … † Mickaël BARON † Ingénieur de Recherche au LIAS † https://www.lias-lab.fr † Equipe : Ingénierie des Données et des Modèles † Responsable des plateformes logicielles, « coach » technique † Ancien responsable Java de Developpez.com (2011-2021) † Communauté Francophone dédiée au développement informatique † https://java.developpez.com † 4 millions de visiteurs uniques et 12 millions de pages vues par mois † 750 00 membres, 2000 forums et jusqu'à 5000 messages par jour mickael-baron.fr mickaelbaron
  4. 4 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Organisation

    du cours sur la boîte à outils SWT † Evolution des boîtes à outils pour Java † Conteneurs † Composants de type Control † Agents de placement † Gestion des événements † Dessiner avec Graphical Context † Les boîtes de dialogue (Message, Couleur, …) † Les indispensables (appel SWT dans des Threads …) † Co-habitation entre SWT et Swing
  5. 5 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Evolution

    des boîtes à outils Java † La bibliothèque AWT (Abstract Window Toolkit) † BAO historique de Java depuis le JDK 1.0 mais toujours utilisable (souvent utilisée directement pour les Applets) † Tous les composants sont implémentés à partir du sous-ensemble « portable » des composants natifs des systèmes hôtes (Heavyweight Component) † L’affichage et le comportement de l’IHM sont fortement liés au système hôte Système graphique : X11, Windows, etc. Peer AWT Application Java Machine virtuelle Tracé graphique Fournit un ensemble d’interface permettant aux composants graphiques d’être représentés à l’écran
  6. 6 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Evolution

    des boîtes à outils Java † La bibliothèque Swing † BAO considérée comme standard en Java 2 Platform (depuis le JDK 2) † Tous les composants sont implémentés directement sans faire appel aux composants natifs du système hôte (Lightweight Components) † L’affichage et le comportement de l’IHM sont indépendants du système hôte et ne dépendent que du programmeur ou de l’utilisateur (Look and Feel) Système graphique : X11, Windows, etc. Peer AWT Application Java Machine virtuelle Swing Tracé graphique
  7. 7 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Boîte

    à outils SWT † SWT : Standard Widget Toolkit † Bibliothèque développée par IBM pour le projet Eclipse † www.eclipse.org/articles/Article-SWT-Design-1/SWT-Design-1.html † Distribuée librement pour le développement de plug-ins ou d’application stand-alone † Fournit des composants de base (bouton, label, …) † Fournit des composants plus complexes avec JFace † Fournit un modèle pour la gestion des événements identique à celui utilisé par AWT et Swing (abonnement)
  8. 8 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Boîte

    à outils SWT Système graphique : X11, Windows, etc. SWT.dll, SWT.so, … SWT Application Java Machine virtuelle Tracé graphique † SWT fournit des techniques d’implémentation de bas niveau † SWT procure des composants graphiques natifs d’une manière indépendante de l’OS † Combinaison de classes Java et JNI spécifiques à chaque plateforme † JNI utilisé pour invoquer le système d’exploitation
  9. 9 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Comparaison

    Swing/SWT † Performance : même si SWT s’appuie sur des composants natifs il y a des cas particuliers où Swing est plus rapide † Affichage de très grand nombre d’information : JTable Swing plus rapide qu’un TextViewer SWT/JFace † Composants natifs = meilleure réactivité et rapidité de chargement † Portabilité : avec SWT nécessité d’utiliser des bibliothèques natives alors que pour Swing aucune contrainte † Pour SWT installation des bibliothèques † Pour Swing déjà pré-installé
  10. 10 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Comparaison

    Swing/SWT (suite) † Look : SWT ne permet pas de modifier l’apparence des composants † Pour SWT respect des habitudes de l’utilisateur † Pour Swing possibilité de s’adapter à un type d’utilisateur (un look cartoon pour les enfants) † Reproche à Swing son aspect non professionnel (à voir) † Développement : SWT nécessite de libérer les ressources pas pour Swing † Pour SWT de nombreux composants adapté (assistant par exemple) † Swing n’est pas en reste avec les composants SwingLabs † Pour Swing plus de documentations pour l’aide au développement † Pour SWT moins d’exemples mais ça arrive …
  11. 11 SWT - M. Baron - Page mickael-baron.fr mickaelbaron SWT

    : les ressources … † Le site de la fondation Eclipse † La page d’accueil sur SWT (www.eclipse.org/swt) † Un ensemble d’exemples (www.eclipse.org/swt/snippets) † Des articles de la fondation Eclipse † www.eclipse.org/articles/Article-SWT-images/graphics-resources.html † www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html † www.eclipse.org/articles/Article-SWT-Design-1/SWT-Design-1.html et 2 † Et pleins d’autres encore … † Des supports de cours et des exemples † www.labo-sun.com/resource-fr-essentiels-903-0-java-gui-swt-creer-des-interfaces- graphiques-performantes.htm † www.java2s.com/Code/Java/SWT-JFace-Eclipse/CatalogSWT-JFace-Eclipse.htm
  12. 12 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Principaux

    composants graphiques de SWT † Fenêtres † Les fenêtres de base et les boîtes de dialogue † Composants † Les principaux composants d’interaction : boutons, menus, Tree, Table, Scale, … † Les composants JFace apporteront une vision MVC des composants † Conteneurs † Composants spécifiques (parfois invisibles) qui servent à contenir des composants et/ou Conteneurs † Les fenêtres sont des conteneurs † Agents de placements † Ce sont des objets qui servent à placer des composants dans un conteneur
  13. 13 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Exemple

    : le compteur file rouge † Le compteur … † Un bouton et un entier sont affichés dans une fenêtre † Lorsque l’utilisateur appuie sur le bouton, l’entier est incrémenté d’une unité puis affiché † Composants graphiques visibles † Une fenêtre principale † Un bouton que l’utilisateur peut déclencher † Une zone de texte non modifiable par l’utilisateur † Réaction aux actions de l’utilisateur † L’événement « clic sur le bouton » doit incrémenter l’entier et l’afficher à nouveau Fenêtre Bouton Label
  14. 14 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    compteur : structure des composants † La fenêtre † Classe : Shell † Le contenu de la fenêtre † La fenêtre est un conteneur de type Composite † Permet d’y ajouter les autres composants † Le bouton et la zone de texte † Classes : Button et Label † Ajoutés au conteneur pour pouvoir s’y afficher Le placement des composants n’est pas encore défini myShell Shell Composite myLabel myButton … Détail plus tard … myShell contient
  15. 15 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    compteur : implémentation † Étapes de développement † Récupération du Display † Création de la fenêtre † Création des composants en les ajoutant à la fenêtre † Dimensionnement de la fenêtre (optionnel) † Affichage de la fenêtre public class Compteur { public Compteur() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); Button myButton = new Button(myShell,SWT.NONE); myButton.setText("i->i+1"); Label myLabel = new Label(myShell, SWT.CENTER); myLabel.setText("i = 0"); myShell.pack(); myShell.open(); while(!myShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } public static void main (String args[]) { new Compteur(); } } Détail plus tard … Compteur.java du projet IntroExamples
  16. 16 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    compteur : résultat de l’affichage … † Le résultat n’est pas celui espéré … † Le placement des composants n’a pas été effectué † Les composants ne sont pas visibles (ils le sont mais leur position et leur taille sont nulles) † Il manque un agent de placement de type Layout † Par défaut il n’y a pas d’agent de placement (null)
  17. 17 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Placement

    d’un composant dans un conteneur † Une IHM en Java peut avoir plusieurs apparences † La taille et le type de police varient † Les composants possèdent différentes représentations † Le placement des composants ne peut se faire de manière absolue † Utilisation d’agents de placement : « Layout Manager » † Un agent de placement est associé à un conteneur † Par défaut il n’y a pas d’agent de placement (null) qui est utilisé dans les conteneurs † L’agent de placement place les composants les uns par rapport aux autres † de la taille préférée de chacun des composants † de la place disponible dans le conteneur † de la politique de placement définie par l’agent de placement
  18. 18 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    compteur : utilisation d’un RowLayout public class CompteurLayout { public CompteurLayout() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); myShell.setLayout(new RowLayout(SWT.VERTICAL)); Button myButton = new Button(myShell,SWT.NONE); myButton.setText("i->i+1"); Label myLabel = new Label(myShell, SWT.CENTER); myLabel.setText("i = 0"); myShell.pack(); myShell.open(); ... } public static void main (String args[]) { new CompteurLayout(); } } † Les composants sont placés par le RowLayout † en respectant leur taille préférée † de haut en bas † la méthode pack() demande le placement automatique des composants † Exemple : le compteur agencé avec RowLayout Le placement est correcte, il faudrait par contre agrandir la taille du bouton en fonction de la fenêtre CompteurLayout.java du projet IntroExamples
  19. 19 SWT - M. Baron - Page mickael-baron.fr mickaelbaron public

    class CompteurLayout2 { public CompteurLayout2() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); myShell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(myShell,SWT.NONE); myButton.setText("i->i+1"); Label myLabel = new Label(myShell, SWT.CENTER); myLabel.setText("i = 0"); myShell.pack(); myShell.open(); while(!myShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } public static void main (String args[]) { new CompteurLayout2(); } } Le compteur : utilisation d’un FillLayout † Les composants sont placés par le FillLayout † de haut en bas (identique au RowLayout sans respect de la taille) † tous les éléments ont la même ligne † Exemple : le compteur agencé avec FillLayout CompteurLayout2.java du projet IntroExamples
  20. 20 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Réalisation

    classique d’une interface graphique † Étapes de la réalisation sans gestion des événements † Création d’une fenêtre avec un objet de type Shell † Création d’un agent de placement et association au conteneur du Shell † Création d’un composant † Ajout du composant au conteneur † Création d’un autre composant † … Utilisez le plus possible des conteneurs pour placer correctement vos composants. C’est gratuit …
  21. 21 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Conception

    d’une interface graphique complexe † Hiérarchisation des composants en arbre de conteneurs † Grouper les composants dans les conteneurs (Composite) avec une politique de placement grâce aux agents de placement † Grouper de nouveaux les composants obtenus Ces composants peuvent être définis localement ou bien être des instances d’autres classes qui hériteraient de Composite
  22. 22 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Conception

    d’une interface graphique complexe † Décomposition des composants de l’application Button(SWT.PUSH) valider Composite haut (RowLayout) Text (SWT.MULTI) myText Shell (GridLayout) Button(SWT.PUSH) annuler Button (SWT.RADIO) sms Button (SWT.RADIO) email Composite bas (FillLayout) bas haut myText
  23. 23 SWT - M. Baron - Page mickael-baron.fr mickaelbaron †

    Exemple : création d’un composant avec du texte un champ † Création du texte avec la classe Label † Création du champ avec la classe Text † Placement dans un Composite † Nouvelle classe LabelText hérite de Composite et pourra ainsi être utilisée comme composant dans une autre application Des composants réutilisables public class CompositeWidgets extends Composite { public CompositeWidgets(Composite parent, String label, String textf) { super(parent, SWT.NONE); GridLayout myGL = new GridLayout(2, false); this.setLayout(myGL); Label myLabel = new Label(this, SWT.NONE); myLabel.setText(label); Text myText = new Text(this,SWT.BORDER); myText.setText(textf); GridData myGD = new GridData(GridData.FILL_BOTH); myText.setLayoutData(myGD); } ... // Suite dans le prochain transparent } CompositeWidgets.java du projet IntroExamples
  24. 24 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Des

    composants réutilisables † Exemple (suite) : création d’un composant personnalisé † Création d’une fenêtre Shell † Création d’une instance du LabelText et ajout au container de la Shell public class CompositeWidgets extends Composite { ... // Suite dans le précédent transparent public static void main(String[] argv) { Display display = new Display (); Shell shell = new Shell (display); shell.setLayout(new FillLayout(SWT.VERTICAL)); new LabelText(shell, "Saisissez le nom", ""); shell.pack (); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } } CompositeWidgets.java du projet IntroExamples
  25. 25 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Des

    concepts de base † SWT utilise des ressources du système d’exploitation † Toutes ressources allouées se doivent d’être libérées † www.eclipse.org/articles/Article-SWT-Design-1/SWT-Design-1.html † Le garbage collector n’est pas capable de libérer la mémoire puisqu’il lui est impossible de connaître l’ordre de libération † Règle 1 : « if you created it, you dispose it » † Libération explicite des ressources graphiques † Nécessité de libérer les ressources par la méthode dispose() Font font = new Font (display, "Courier", 10, SWT.NORMAL); ... // Utilisation de l’objet fond font.dispose(); Détruire les objets Font font = ref.getFont(); ... // Utilisation de l’objet fond Ne pas détruire les objets Récupération d’un objet Création d’un objet
  26. 26 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Des

    concepts de base † Règle 2 : « disposing the parent, dispose the children » † Un composant ne peut pas exister dans le système d’exploitation sans composant parent † Création du conteneur obligatoirement avec le contenu † Contrôle du cycle de vie via la relation parent-enfant exprimée via le constructeur † Si le composant parent est libéré, les composants enfants seront automatiquement libérés public class Compteur { public Compteur() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); Button myButton = new Button(myShell,SWT.NONE); ... } ... } A la construction des composants, obligation d’indiquer le conteneur Les composants non graphiques Font, Color, … ne sont pas des enfants et devront être libérés … Si myShell libéré tous ces enfants le sont aussi
  27. 27 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    Display † Rôle et caractéristiques de la classe Display † Effectue la connexion entre l’application Java et le système d’exploitation hôte † Fournit le mécanisme de traitement des événements † Package : org.eclipse.swt.widgets.Display † Quelques méthodes utiles de la classe Display † static Display getCurrent() ou getDefault() : récupère un Display † Rectangle getBounds() : récupère la taille de l’écran † Color getSystemColor(String id) : effectue la relation entre les couleurs de SWT et du système † boolean readAndDispatch() : transfert les événements du système à l’application, retourne vraie s’il y a encore des événements † setCursorLocation(int x, int y) : déplace le pointeur de l’écran
  28. 28 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Le

    Display † La fonction principale de l’objet Display est la gestion de la boucle principale d’événements † En comparaison avec la boite à outils Swing où la boucle est implicite, SWT nécessite de définir explicitement une boucle † Définition d’une boucle d’événement public class Compteur { public Compteur() { ... while(!myShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } } readAndDispatch() récupère les événements du système hôte et les transmet à l’application Tant que la fenêtre en « vie » readAndDispatch continue à dispatcher Si readAndDispatch() retourne vraie des événements sont encore à traiter Si readAndDispatch() retourne faux mise en attente jusqu’à l’arrivée de nouveaux événements
  29. 29 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Erreurs

    et Exceptions † SWT distingue trois types d’exceptions † SWTError † Levée lors d’une erreur fatale † Une erreur irrécupérable † SWTException † Levée lors d’une erreur non fatale † Une erreur récupérable † Exemple : Invalid thread access † IllegalArgumentException † Exception levée lors d’une erreur non fatale † Un argument fourni est invalide † Exemple : argument ne peut être null
  30. 30 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    hiérarchie des packages SWT † org.eclipse.swt : package de base qui contient la définition des constantes (SWT) et des exceptions † org.eclipse.swt.accessibility : package concernant l’accessibilité † org.eclipse.swt.awt : package permettant l’intégration de composants Swing dans SWT † org.eclipse.swt.browser : package concernant le composant browser † org.eclipse.swt.custom : composants particuliers (TableTree) † org.eclipse.swt.dnd : support du Drag&Drop † org.eclipse.swt.events : pour la gestion des événements
  31. 31 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    hiérarchie des packages SWT † org.clipse.swt.graphics : ensemble de classes pour le graphique † org.eclipse.swt.layout : agents de placement † org.eclipse.swt.ole.win32 : gestion OLE pour Windows † org.eclipse.swt.printing : pour la gestion de l’impression † org.eclipse.swt.program : exécution d’application sur l’OS † org.eclipse.swt.widgets : API des composants graphiques Dans la suite de ce cours nous allons nous intéresser plus particulièrement aux packages widgets, graphics, events, layout et awt
  32. 32 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    hiérarchie des composants SWT † Hiérarchie des principaux composants Control Widget Tray Scrollable Composite Menu … Button Label … Combo Browser … Text List Les sous-classes de Control, Scrollable et Composite seront étudiées dans ce cours
  33. 33 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    hiérarchie des composants SWT † La classe Widget est la classe de plus haut niveau pour les composants graphiques † Sous-classes de Control † Service : composants fils à une fenêtre avec réaction à enregistrement à des événements de base (MouseListener, KeyListener, …) † Exemples : Button, Label † Sous-classes de Scrollable † Service : composants avec des barres de défilement † Exemple : List, Text † Sous-classes de Composite † Service : composants capable de contenir des composants Control appelés également conteneur † Exemple : Canvas, Group
  34. 34 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    classe Widget † La classe Widget est la classe de plus haut niveau de la hiérarchie SWT † Services proposés † Mécanisme générique de bas niveau pour la gestion des événements † Sémantique de construction et de destruction † Mécanisme de stockage d’information † Méthodes usuelles † void dispose() : libérer les ressources d’un composant † Display getDisplay() : récupère le Display associé au composant † addListener(int, Listener) : mécanisme d’abonnement † … † Cette classe ne peut être étendue pour le développement
  35. 35 SWT - M. Baron - Page mickael-baron.fr mickaelbaron La

    classe Control † La classe Control dérive de la classe Widget et chaque objet Control encapsule un composant graphique natif : un peer † Tous les composants SWT à l’exception de ScrollBar et Menu sont des Control † La classe Control fournit des méthodes pour contrôler l’affichage et le comportement † Taille, couleur, police, menu popup, … † Abonnement aux écouteurs (listeners typés) † De nombreuses méthodes … se référer à l’API
  36. 36 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Galerie

    des composants : conteneurs Shell Composite CoolBar ToolBar Combo Spinner Canvas Browser
  37. 37 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Galerie

    des composants : conteneurs (suite) Tree Table StyledText CTabFolder ExpandBar Group TabFolder ScrolledComposite
  38. 38 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Galerie

    des composants : contrôle Button (SWT.ARROW) Button (SWT.PUSH) Button (SWT.CHECK) Button (SWT.TOGGLE) Button (SWT.RADIO) Link Label
  39. 39 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Galerie

    des composants : contrôle (suite) Slider Scale Text (SWT.SINGLE) Text (SWT.MULTI) Sash List
  40. 40 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Galerie

    des composants : les autres Menu Tray System
  41. 41 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : Shell † Shell permet la création d’une fenêtre (équivalent à la JFrame de Swing) † Fenêtre indépendante dont l’apparence peut varier en fonction du style donné lors de la construction † Possibilité de créer des sous fenêtres associées une fenêtre parent † Construction † Shell(Display) : construit un Shell (style défaut) associé à un Display † Shell(Display, int) : avec un style défini † Shell(Shell) : construit un Shell associé à un Shell parent † Méthodes utiles † setVisible(boolean) : rend visible ou pas la fenêtre † open() : appel un ensemble de fonctionnalités (visible, active, …)
  42. 42 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : Shell † Les styles d’une fenêtre (constantes de la classe SWT) † BORDER : ajoute un border † CLOSE : ajoute un bouton de fermeture † MIN : ajoute un bouton pour minimiser la fenêtre † MAX : ajoute un bouton pour maximiser la fenêtre † RESIZE : ajoute un border pour le redimensionnement † TITLE : ajoute une barre de menu † Paramètres pré-définis † NO_TRIM : fenêtre sans possibilité de redimensionner, agrandir, minimiser, déplaçable, border, … † DIALOG_TRIM : TITLE | CLOSE | BORDER † SHELL_TRIM : CLOSE | TITLE | MIN | MAX | RESIZE
  43. 43 SWT - M. Baron - Page mickael-baron.fr mickaelbaron †

    Les fenêtres modales † SYSTEM_MODAL : modale au système complet (peu répandu) † APPLICATION_MODAL : création d’une fenêtre modale à l’application † PRIMARY_MODAL : création d’une fenêtre modale † MODE_LESS : non modale Les conteneurs de SWT : Shell NO_TRIM DIALOG_TRIM SHELL_TRIM
  44. 44 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : Composite † La classe Composite s’occupe de la gestion des conteneurs † Elle peut contenir des composants Control et par conséquent d’autres objets de type Composite † Un objet Composite doit être rattaché directement à un objet Shell, ou indirectement via d’autres conteneurs † Les composants sont ajoutés au conteneur au moment de la construction des composants (En Swing les composants sont ajoutés par l’intermédiaire de la méthode add du conteneur)
  45. 45 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : Composite † Un conteneur gère l’agencement des composants par un agent de placement † Différentes méthodes utiles † Composite(Composite, int) : constructeur d’un Composite † layout(boolean) : active ou pas l’agencement † setLayout(Layout) : modifie l’agent de placement † Control[] getChildren() : retourne le nombre de Control contenu † setFocus() : affecte le focus au conteneur La classe Shell étudiée précédemment est du type Composite
  46. 46 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : Group † Le conteneur Group est similaire à la classe Composite, il impose une délimitation et permet d’ajouter un titre † En Swing, il s’agit d’un JPanel décoré d’un TitledBorder † Différentes méthodes utiles † setText(String p) : modifie le titre du Group † String getText() : récupère le titre du Group † Exemple : des composites décorés Group temp = new Group(sShell, SWT.NONE); temp.setText("Action"); temp.setLayout(new FillLayout(SWT.HORIZONTAL)); Button myButton = new Button(temp, SWT.NONE); myButton.setText("i -> i + 1"); temp = new Group(sShell, SWT.NONE); temp.setText("Résultat"); temp.setLayout(new FillLayout(SWT.HORIZONTAL)); Label myLabel = new Label(temp,SWT.CENTER); myLabel.setText("i = " + i); }
  47. 47 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : ToolBar † ToolBar permet d’ajouter une barre d’outils en contenant un ensemble de composants prédéfinis (Button, Toggle, …) † Une ToolBar peut être horizontale ou verticale † Chaque élément d’une barre d’outil est défini par un ToolItem † Apparence d’un ToolItem (constantes de la classe SWT) † CHECK : un bouton de sélection (Toggle) † DROP_DOWN : un bouton avec un chevron † PUSH : un bouton classique † RADIO : un bouton de type radio (singleton sur la sélection) † SEPARATOR : un séparateur ToolBar toolBar = new ToolBar(shell, SWT.HORIZONTAL) Ou ToolBar toolBar = new ToolBar(shell, SWT.VERTICAL)
  48. 48 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : ToolBar † Différentes méthodes pour ToolItem † setControl(Control) : modifie le contrôle quand l’item est un séparator † setSelection(boolean) : sélectionne ou pas † setEnabled(boolean) : active ou désactive † setText(String) : modifie le texte † setToolTipText(String) : modifie la bulle d’aide † setWidth(int) : modifie la taille en pixel de l’élément † Utilisation de la méthode setControl(Control) † Possibilité d’ajouter des composants Control à la ToolBar † Nécessite que le style du ToolItem soit SEPARATOR
  49. 49 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : ToolBar † Exemple : une barre d’outils … public class ToolBarExample { public ToolBarExample() { Display display = new Display (); Shell shell = new Shell (display); ToolBar bar = new ToolBar (shell, SWT.HORIZONTAL); ToolItem item = new ToolItem (bar, SWT.PUSH); item.setText("Item 1"); Button myButton = new Button(bar,SWT.NONE); myButton.setText("Ici"); item = new ToolItem(bar,SWT.SEPARATOR); myButton.pack(); item.setWidth(myButton.getSize().x); item.setControl(myButton); bar.pack (); shell.pack (); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); ... } Ajout d’un objet Control dans la barre de menu ToolBarExample.java du projet IntroExamples
  50. 50 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    conteneurs de SWT : CoolBar † La CoolBar fonctionne sur le même principe que la ToolBar à la différence où les éléments sont flotants † Pour interdire le déplacement d’éléments dans une CoolBar utiliser la méthode setLocked(boolean) † Les éléments contenus dans une CoolBar sont définis par des CoolItem Element déplaçable Element déplaçable
  51. 51 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    composants de contrôle : Button † La classe Button représente un bouton cliquable † A la différence de Swing où chaque type de bouton à une classe prédéfinie (JButton, JRadioButton, JCheckBox, …) le SWT se base sur les styles † Différentes méthodes utiles † setText(String) : modifie le texte du bouton † setSelection(boolean) : modifie la sélection † Différentes apparences (constantes de la classe SWT) † PUSH ou NONE : bouton par défaut † CHECK : case à cocher † RADIO : bouton radio † TOGGLE : bouton de sélection † ARROW : bouton avec flèche
  52. 52 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    composants de contrôle : Button † Exemple : un ensemble de boutons public class ButtonsExample { public ButtonsExample() { Display display = new Display (); Shell shell = new Shell (display); shell.setText("Buttons Example"); shell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(shell,SWT.PUSH); myButton.setText("Push Me"); myButton = new Button(shell,SWT.CHECK); myButton.setText("Check Me"); myButton = new Button(shell,SWT.RADIO); myButton.setText("Radio Me"); myButton = new Button(shell,SWT.RADIO); myButton.setText("Radio Me"); myButton = new Button(shell,SWT.TOGGLE); myButton.setText("Select Me"); myButton = new Button(shell,SWT.ARROW); myButton.setText("Turn Me"); ... } Les boutons de type RADIO sont groupés s’ils appartiennent au même Composite ButtonsExample.java du projet IntroExamples
  53. 53 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    composants de contrôle : Label et Text † La classe Label permet d’afficher un texte ou une image † setText(String) : modifie le texte † setImage(Image) : modifie l’image † La classe Text est une zone de texte contenant une ou plusieurs ligne (SINGLE ou MULTI) † setText(String) : modifie le texte † setTextLimit(int) : définit la limite de la chaîne † setEditable(boolean) : précise si la zone de texte est éditable † Exemple : un ensemble de textes public class LabelTextExample { public LabelTextExample() { Display display = new Display (); Shell shell = new Shell (display); shell.setText("Buttons Example"); shell.setLayout(new FillLayout(SWT.VERTICAL)); Label myLabel = new Label(shell, SWT.BORDER); myLabel.setText("Message"); Text myText = new Text(shell, SWT.BORDER | SWT.MULTI); myText.setText("Coucou"); ... } LabelTextExample.java du projet IntroExamples
  54. 54 SWT - M. Baron - Page mickael-baron.fr mickaelbaron L’art

    de placer les composants SWT † Les agents de placement ou Layout Manager FillLayout RowLayout FormLayout GridLayout StackLayout
  55. 55 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement et les composants † Les agents de placement permettent d’agencer les widgets contenus dans un objet Composite † Un agent de placement hérite de classe Layout † Il peut s’agir de composants de type Control ou Composite † L’agent de placement est associé à un objet Composite † setLayout(Layout) : modification d’un agent de placement † Chaque widget peut influencer son comportement dans son conteneur par la méthode † setLayoutData(Object) : objet spécifique suivant le type d’agent de placement † Pour appliquer l’agencement et le re-dimensionnement des objets Control, utiliser la méthode pack()
  56. 56 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FillLayout † Affiche horizontalement ou verticalement les composants les uns à la suite des autres † VERTICAL ou HORIZONTAL constantes de la classe SWT † Tous les composants sont redimensionnés de manière identique, ne conserve donc pas la taille des composants † Dés que le conteneur est redimensionné les composants se distribuent l’espace † Exemple : boutons alignés verticalement sShell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 1"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 2"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 3"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 4"); FillLayout.java du projet LayoutExamples
  57. 57 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : RowLayout † Affiche horizontalement ou verticalement les composants les uns à la suite des autres (si possible) † VERTICAL ou HORIZONTAL constantes de la classe SWT † Possibilité de conserver la taille des composants † Si pas assez de place débordement sur une nouvelle ligne ou une colonne † Peut être comparé à l’agent de placement FlowLayout de Swing (mais en plus expressif) † Possibilité de contraindre chaque composant par un objet de type RowData † RowData(int width, int height) : largeur et hauteur
  58. 58 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : RowLayout † RowLayout peut être paramétré après sa construction † boolean justify : précise si les composants doivent être justifiés † int marginBottom, marginTop : marge du bas et du haut † int marginLeft, marginRight : marge à gauche et à droite † boolean pack : si true les composants gardent leur taille préférée † int spacing : espace entre les contrôles † int type : orientation (SWT.VERTICAL ou SWT.HORIZONTAL) † boolean wrap : si true retour à la ligne quand plus de place
  59. 59 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : RowLayout RowLayout myLayout = new RowLayout(SWT.HORIZONTAL); myLayout.wrap = true; sShell.setLayout(myLayout); Button myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 1"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 2"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 3"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 4"); myButton.setLayoutData(new RowData(100,100)); † Exemple : un ensemble de boutons Le dernier bouton est agrandi Différents résultats en fonction de la taille de la fenêtre RowLayoutExample.java du projet LayoutExamples
  60. 60 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : GridLayout † L’agent de placement GridLayout est un des plus expressif et pourrait être suffisant † Il contrôle une grille avec la possibilité de fusionner des cellules et de contraindre ou pas la largeur des cellules † Comparable au GridLayout de Swing en plus expressif † Construction d’un GridLayout † GridLayout(int nc, boolean ew) : construit un GridLayout avec nc nombre de colonnes. Si ew = true les colonnes ont la même taille † GridLayout() : construit un GridLayout avec une colonne et les colonnes n’auront pas la même taille
  61. 61 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : GridLayout † GridLayout peut être paramétré après sa construction † int horizontalSpacing : espace horizontal entre les cellules † int verticalSpacing : espace vertical entre les cellules † boolean makeColumnsEqualWidth : true = force toutes les colonnes à avoir la même taille † int marginHeight, marginWidth : marge en largeur et en hauteur † int numColumns : nombre de colonne † Possibilité de contraindre chaque composant par un objet de type GridData † GridData(int style) : construit un GridData avec un style spécifié
  62. 62 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : GridLayout † GridData peut être paramétré après sa construction † int horizontalSpan : le nombre de colonne occupé † int verticalSpan : le nombre de ligne occupé † int horizontalAlignment : précise le type d’alignement GridData.FILL, .BEGINNING, .CENTER et .END † boolean grabExcessHorizontalSpace : si TRUE force la cellule à remplir l’espace disponible † … † Les différentes constantes utilisables † FILL_BOTH : rempli l’espace disponible horizontal et vertical † FILL_HORIZONTAL : rempli l’espace disponible horizontal † FILL_VERTICAL : rempli l’espace disponible vertical † … FILL, BEGINNING, CENTER et END ne sont pas utilisables pour construire un GridData
  63. 63 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : GridLayout † Exemple : un ensemble de boutons GridLayout myLayout = new GridLayout(3, false); sShell.setLayout(myLayout); Button myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 1"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 2"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 3"); myButton = new Button(sShell, SWT.NONE); myButton.setText("Bouton 4"); GridData myData = new GridData(GridData.FILL_BOTH); myData.horizontalSpan = 3; myButton.setLayoutData(myData); Trois cellules en haut Trois cellules fusionnées GridLayoutExample.java du projet LayoutExamples
  64. 64 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † L’agent de placement FormLayout organise les Control en exploitant des contraintes de placement † Comparable au GridBagLayout de Swing † Possibilité de contraindre chaque composant par un objet de type FormData † Utilisation d’un objet additionnel FormAttachment lié au FormData pour contrôler la taille et le placement † Attributs d’un FormData † int height, width : hauteur et largeur pour le Control † FormAttachment bottom, left, right, top : la contrainte pour le bas, la gauche, la droite et le haut du Control
  65. 65 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † FormAttachment définit comment les composants sont positionnés entre eux † Cet objet permet de définir l’alignement et la taille d’un Control † Un FormAttachment peut être associé à un Control pour définir ainsi des contraintes entre objets Control † Représentation mathématique de l’objet FormAttachment sous la forme d’une équation de type : y = a x + b † y = coordonnées après attachement † x = coordonnées avant attachement † a = pourcentage de l’objet attaché ( a = numérateur / dénominateur) † b = offset
  66. 66 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Attributs d’un FormAttachment † int alignment : côté du Control avec lequel le FormAttachment sera attaché SWT.TOP, .CENTER, .BOTTOM, .LEFT, .RIGHT † Control control : l’objet Control associé au FormAttachment † int denominateur : dénominateur de a (défaut : 100) † int numerator : numérateur de a † int offset : décalage † Construction d’un FormAttachment † FormAttachment(Control p, int offset) † FormAttachment(int numerator, int offset) † FormAttachment(int numerator, int denominateur, int offset) † …
  67. 67 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Exemple (EP 1) : FormLayout sans FormAttachment FormLayout formLayout = new FormLayout(); shell.setLayout(formLayout); FormData formData = new FormData(); formData.height = 120; formData.width = 120; Button button = new Button(shell, SWT.PUSH); button.setLayoutData(formData); button.setText("Button 1"); Le bouton conserve sa taille préférée lors de l’agrandissement de son container FormLayoutExample1.java du projet LayoutExamples
  68. 68 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Exemple (EP 2) : FormLayout avec FormAttachment FormLayout formLayout = new FormLayout(); shell.setLayout(formLayout); FormData formData = new FormData(); formData.height = 120; formData.width = 120; formData.left = new FormAttachment(0,20); formData.right = new FormAttachment(100,-20); formData.top = new FormAttachment(0,20); formData.bottom = new FormAttachment(100,-20); Button button = new Button(shell, SWT.PUSH); button.setLayoutData(formData); button.setText("Button 1"); Fixé à 20 pixels à gauche Fixé à 20 pixels à droite Fixé à 20 pixels en haut Fixé à 20 pixels en bas Le bouton est collé au partie droite et basse FormLayoutExample2.java du projet LayoutExamples
  69. 69 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Exemple (EP 2) bis : FormLayout avec FormAttachment Côté droit y = (100 / 100) x - 20 Côté gauche y = (0 / 100) x + 20 A chaque re-dimensionnement du conteneur la position du côté droit du bouton varie linéairement A chaque re-dimensionnement du conteneur la position du côté gauche du bouton ne change pas x (coordonnées avant attachement) x (coordonnées après attachement)
  70. 70 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Exemple (EP 2) bis : FormLayout avec FormAttachment Numérateur = 0, offset > 0 Numérateur = 100, offset < 0 Numérateur = 0, offset > 0 Numérateur = 100, offset > 0 Valeurs pour les cas généraux du moment que les FormAttachment ne sont pas liés à un Control
  71. 71 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : FormLayout † Exemple (EP 3) : FormLayout avec FormAttachment et Control associé FormLayout formLayout = new FormLayout(); shell.setLayout(formLayout); Button button1 = new Button(shell, SWT.PUSH); button1.setText("Button 1"); Button button2 = new Button(shell, SWT.PUSH); button2.setText("Button 2"); FormData formData = new FormData(); formData.left = new FormAttachment(0,20); formData.right = new FormAttachment(100,-20); formData.top = new FormAttachment(0,20); formData.bottom = new FormAttachment(button2,0,SWT.TOP); button1.setLayoutData(formData); formData = new FormData(); formData.left = new FormAttachment(0,20); formData.right = new FormAttachment(100,-20); formData.bottom = new FormAttachment(100,-20); formData.top = new FormAttachment(1,2,0); button2.setLayoutData(formData); Relier le bas de bouton1 avec le haut du bouton2 FormLayoutExample3.java du projet LayoutExamples
  72. 72 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : StackLayout † L’agent de placement StackLayout permet d’empiler des Control et de choisir celui qui sera visible † Similaire au CardLayout de Swing † Ne fait pas partie du package org.eclipse.swt.layout † StackLayout peut être paramétré après sa construction † int marginHeight : marge en hauteur † int marginWidth : marge en largeur † Control topControl : objet Control à afficher † Si l’objet topControl est null aucun objet Control ne sera affiché † Pour changer d’objet Control à afficher † Modifier l’objet contenu dans topControl du StackLayout † Appeler layout() du Composite
  73. 73 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : StackLayout † Exemple : StackLayout et deux boutons final Shell shell = new Shell (display); final StackLayout stackLayout = new StackLayout(); shell.setLayout(stackLayout); Button button1 = new Button(shell, SWT.PUSH); button1.setText("Button 1"); final Button button2 = new Button(shell, SWT.PUSH); button2.setText("Button 2"); button1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { stackLayout.topControl = button2; shell.redraw(); } }); stackLayout.topControl = button1; A la suite de l’action sur button1, button2 devient l’objet Control courant dans le StackLayout FormLayoutExample3.java du projet LayoutExamples
  74. 74 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : aucun … † Ne pas utiliser d’agent de placement vous impose pour chaque composant de : † les positionner dans leur parent † définir la taille † L’absence d’agent de placement ne permet pas de produire des interfaces qui s’adaptent au système † Pour préciser que vous ne voulez pas d’agent de placement donner une valeur null à la méthode setLayout(…) † Dans quels cas ne pas utiliser d’agent de placement † Construction d’un GUI-Builder
  75. 75 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    agents de placement : aucun … † Exemple : sans agent de placement avec 2 boutons Shell shell = new Shell (display); shell.setLayout(null); Button button = new Button(shell, SWT.PUSH); button.setText("Button 1"); button.setBounds(0, 0, 125, 125); button = new Button(shell, SWT.FLAT); button.setText("Button 2"); button.setBounds(0, 125, 125, 125); button = new Button(shell, SWT.FLAT); button.setText("Button 3"); button.setBounds(0, 250, 125, 125); Le LayoutManager du Shell est null Modification de la position et de la taille pour chaque composant StackLayoutExample.java du projet LayoutExamples
  76. 76 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Conception

    et programmation † Affichage des informations vers l’utilisateur † Instanciation des composants de la BAO SWT † Mise en place des composants visibles grâce à des conteneurs et agents de placement † Mais l’interface ne peut pas réagir aux actions de l’utilisateur † Clic sur le bouton † Terminaison de l’application † Réaction aux actions de l’utilisateur † En SWT, toute interaction est encapsulée dans un événement † Le traitement des interactions revient à récupérer et interpréter les événements † SWT utilise le principe de l’abonnement
  77. 77 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements SWT † Chaque composant de l’interface graphique peut émettre des événements † C’est une source (Widget) † Des objets peuvent recevoir ces événements † Ce sont des écouteurs (les listeners) † La liaison entre source et écouteur se fait par abonnement † On associe à une source un ou plusieurs écouteurs et réciproquement † SWT fournit deux types de listeners † Les listeners non typés (Listener) † Les listeners typés (EventListener) † Les événements sont définis par une classe Java qui dépend du type de listener † Event pour les listeners non typés † TypedEvent pour les listeners typés
  78. 78 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Intérêt

    du traitement par abonnement † Exemple d’un compteur qui incrémente et décrémente † Deux boutons † « OUI » incrémente une variable † « NON » décrémente la même variable † Un son est émis à chaque pression sur un des boutons † Un bouton est associé deux fois à un même événement avec deux actions différentes +1 -1 Beep ! SelectionEvent SelectionEvent SelectionEvent
  79. 79 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Intérêt

    du traitement par abonnement † En quoi consiste l’abonnement ? † Enregistrer (abonner) auprès de l’objet source un écouteur † Exemple : † Qu’est-ce qu’un écouteur ? † Une classe (même anonyme) qui implémente une interface (au sens Java du terme) monBouton.addListener(monListener); Selon le type d’écouteur, la méthode d’abonnement et la classe de l’écouteur varient
  80. 80 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements : les listeners non typés † Les listeners non typés sont représentés par l’interface Listener contenant une seule méthode † void handleEvent(Event event) : méthode de traitement d’un événement † L’abonnement à cet écouteur non typé est effectué par la méthode (présente dans la classe Widget) † void addListener(int eventType, Listener listener) : méthode réalisant l’abonnement entre une source (Widget) et un objet de type Listener pour le type d’événement défini par eventType button.addListener(SWT.SELECTION, new Listener() { public void handleEvent(Event e) { switch(e.type) { case SWT.SELECTION : System.out.println("Button Pressed"); break; } } } button est une source Abonnement de button avec un listener pour écouter un événement SELECTION Traitement de l’événement
  81. 81 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements : les listeners non typés † Le type d’événement à considérer au cours de l’abonnement est défini par des constantes de type int stockées dans SWT † Activate : fenêtre active † Close : widget terminé † Collapse : un nœud d’arbre réduit † Deactivate : fenêtre non active † Dispose : composant détruit † Expand : un nœud d’arbre éclaté † FocusIn : widget gagne le focus † FocusOut : widget perd le focus † KeyDown : presse une touche clavier † KeyUp : relacher une touche clavier † MouseEnter : souris entre dans un widget † MouseExit : souris sort du widget † MouseHover : souris au dessus du widget † MouseMove : souris se déplace dans widget † MouseUp : bouton souris relaché † MouseDown : bouton souris pressé † MouseDoubleClick : pour le double click † Move : déplacement d’un widget † Paint : le widget est dessiné † Resize : widget rediemensionné † Selection : widget sélectionné † Show : widget affiché † …
  82. 82 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements : les listeners non typés † La classe Event permet de définir le contenu de l’événement † Elle contient des attributs qui caractérisent l’événement † Certains attributs sont dépendants du type d’événement considéré † Par exemple pour l’événement de type MouseDoubleClick † int button : modélise le bouton de la souris : 1 pour le bouton de gauche, 2 pour le second et 3 pour le troisième † int type : le type de l’événement considéré † int time : la date à laquelle l’événement a été provoquée † int x et y : position de la souris † Widget item : la source de l’événement
  83. 83 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements : les listeners non typés † Exemple : un bouton et des réactions ... myButton.addListener(SWT.MouseDoubleClick, new Listener() { public void handleEvent(Event event) { System.out.println("Type de l'événement : " + event.type); ((Button)event.widget).setText("DoubleClick"); System.out.println("Date de déclenchement : " + event.time); System.out.println("Position x et y : " + event.x + " / " + event.y); System.out.println("Quel bouton ? : " + event.button); } }); ... InfoEventExample.java du projet EventExamples
  84. 84 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Traitement

    des événements : les listeners typés † Les listeners typés sont représentés par un ensemble d’interface stockés dans le package org.eclipse.swt.events † Les listeners typés fournissent en quelque sort une encapsulation du type d’événement † Pour chaque famille d’événement un listener est proposé † MouseListener : écouteur adapté pour les événements de clicks de la souris † Chaque listener propose un ensemble de méthodes associé à un type précis d’événement † mouseDoubleClick(MouseEvent e) : pour le double click † mouseDown(MousEvent e) : quand le bouton est pressé † mouseUp(MouseEvent e) : quand le bouton est levé
  85. 87 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement † Créer une source † Instancier un composant (e.g. un Button) pour l’affichage, c’est automatiquement une source d’événements † Ne pas oublier de garder une référence disponible sur ce composant † Créer un écouteur † Implémenter dans une classe une des interfaces du package events (e.g. un SelectionListener) selon le type d’événement écouté † Coder les effets de bord attendus dans une des méthodes de cette classe (e.g. public void widgetSelected(SelectionEvent)) † Instancier un objet de cette classe † Abonner l’écouteur à la source † Abonner l’instance de la source à l’instance de l’écouteur
  86. 88 SWT - M. Baron - Page mickael-baron.fr mickaelbaron †

    Créer le composant Button † Créer l’écouteur des SelectionEvent † Implémenter l’interface SelectionListener † Insérer les effets de bord dans la méthode † public void widgetSelected(SelectionEvent evt) † Abonner l’écouteur à l’objet émetteur d’événements † Utiliser la méthode d’abonnement proposée par le composant source † addSelectionListener(SelectionListener al) Programmation du traitement : exemple SelectionEvent ControlEvent KeyEvent MouseEvent … Selection Listener
  87. 89 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement : exemple † Exemple : un bouton abonné à un SelectionListener public class CompteurWithEvent { private int i = 0; private Label myLabel; public CompteurWithEvent() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); myShell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(myShell,SWT.NONE); myButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { i++; myLabel.setText("i = " + i); } }); myButton.setText("i->i+1"); myLabel = new Label(myShell, SWT.CENTER); myLabel.setText("i = 0"); ... } } Méthode implémentée à vide car pas utile Nécessite que myLabel soit vu comme attribut de la classe CompteurWithEvent.java du projet EventExamples
  88. 90 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement : exemple † Exemple : une fenêtre qui ne se ferme pas … public class CloseShellExample { public CloseShellExample() { Display display = new Display(); final Shell myShell = new Shell(display); shell.setLayout(new FillLayout()); shell.setText("CloseShellExample"); shell.addShellListener(new ShellAdapter() { public void shellClosed(ShellEvent event) { event.doit = false; } }); Button myButton = new Button(shell, SWT.FLAT); myButton.setText("Une fenêtre qui ne se ferme pas comme d'habitude"); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { shell.dispose(); } }); ... } } Quand une fenêtre est fermée, elle est disposée. Pour empêcher le dispose Il faut cliquer sur le bouton pour fermer la fenêtre CloseShellExample.java du projet EventExamples
  89. 91 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement : exemple † Certaines interfaces écouteur (Listener) ont une équivalence adaptateur (Adapter) † Une classe adaptateur est une implémentation à vide d’un écouteur † De façon générale s’il y a plus d’une méthode à implémenter un adapter est obligatoirement fourni † En utilisant un adaptateur de l’héritage est effectuée et plus précisément de la re-définition de méthodes † Inversement une interface nécessite une implémentation de l’ensemble des méthodes
  90. 92 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement : exemple † Exemple : un bouton abonné à un SelectionListener par l’intermédiaire d’un adapter public class CompteurWithEvent2 { private int i = 0; private Label myLabel; public CompteurWithEvent2() { Display display = new Display(); Shell myShell = new Shell(display); myShell.setText("Compteur"); myShell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(myShell,SWT.NONE); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { i++; myLabel.setText("i = " + i); } } myButton.setText("i->i+1"); myLabel = new Label(myShell, SWT.CENTER); myLabel.setText("i = 0"); ... } } Héritage de la classe SelectionAdapter Nécessite que myLabel soit vu comme attribut de la classe Faites attention lors de la re-définition des méthodes à ne pas vous tromper dans leur signature CompteurWithEvent2.java du projet EventExamples
  91. 93 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Programmation

    du traitement : les recettes † Pour abonner un composant à un écouteur trois recettes sont envisageables † Abonnement par un écouteur externe † Une classe externe s’occupe spécifiquement du fonctionnement de l’écouteur † Abonnement par un écouteur interne † La classe où se trouve les sources (la partie graphique) sert également d’écouteur † Abonnement par un écouteur locale † Pour chaque abonnement avec une source, utilisation d’une classe anonyme « inner class » † Exemple : abonnement d’un bouton à MouseListener (cet écouteur possède trois méthodes)
  92. 94 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Abonnement

    par un écouteur externe † La définition de l’écouteur se fait en dehors de la classe Exemple † Il faut implémenter chacune des méthodes même s’il n’y a rien à mettre dedans † Difficulté d’accéder aux attributs de la classe Exemple public class Exemple { ... public Exemple() { ... myBut.addMouseListener(new EcouteurInterface()); } } public class EcouteurInterface implements MouseListener { public void mouseDoubleClick(MouseEvent e) { ... } public void mouseDown(MouseEvent e) { } public void mouseUp(MouseEvent e) { } } Cet écouteur est utilisé par la classe Exemple
  93. 95 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Abonnement

    par un écouteur externe : adapter † La définition de l’écouteur se fait en dehors de la classe Exemple † Il faut redéfinir chacune des méthodes même s’il n’y a rien à mettre dedans † Difficulté d’accéder aux attributs de la classe Exemple public class EcouteurAdapter extends MouseAdapter { public void mouseDoubleClick(MouseEvent e) { ... } public void mouseUp(MouseEvent e) { ... } } public class Exemple { ... public Exemple() { ... myBut.addMouseListener(new EcouteurAdapter()); } } Cet écouteur est utilisé par la classe Exemple Redéfinition uniquement des méthodes nécessaires
  94. 96 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Abonnement

    par un écouteur interne public class Exemple implements MouseListener { ... public Exemple() { ... myBut.addMouseListener(this); } public void mouseDoubleClick(MouseEvent e) { this.myBut... } public void mouseDown(MouseEvent e) { } public void mouseUp(MouseEvent e) { } } † La définition de l’écouteur se fait dans la classe Exemple par implémentation † Il faut implémenter chacune des méthodes même s’il n’y a rien à mettre dedans † Possibilité d’accéder facilement aux attributs de la classe Exemple Accès aux attributs de la classe Implémentation à vide
  95. 97 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Abonnement

    par un écouteur locale : interface † La définition de l’écouteur se fait dans une « inner classe » par implémentation et localement à la classe Exemple † Il faut implémenter toutes les méthodes même s’il n’y a rien dedans † Possibilité d’accéder facilement aux attributs de la classe Exemple public class Exemple { ... public Exemple() { ... myBut.addMouseListener(new MouseListener() { public void mouseDoubleClick(MouseEvent e) { Exemple.this.myBut... } public void mouseDown(MouseEvent e) { } public void mouseUp(MouseEvent e) { } }); } } Implémentation à vide Accès aux attributs de la classe
  96. 98 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Abonnement

    par un écouteur locale : adapter public class Exemple { ... public Exemple() { ... myBut.addMouseListener(new MouseAdapter() { public void mouseDoubleClick(MouseEvent e) { Exemple.this.myBut... } }); } } † La définition de l’écouteur se fait dans une « inner classe » par dérivation et localement à la classe Exemple † Il faut redéfinir les méthodes dont on a besoin † Possibilité d’accéder facilement aux attributs de la classe Exemple † Cette solution et la précédente sont à utiliser si le traitement de l’écouteur est utilisé par une seule source Ne vous trompez pas dans la signature des méthodes sinon risque de définition de nouvelles méthodes
  97. 99 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context † Possibilité de dessiner en utilisant la classe GC (Graphical Context) sur des Control, Image et Device † GC fournit un ensemble de méthodes pour dessiner des formes, des textes et des images † Principe † Récupération ou création du GC † Traitement du dessin † Si le GC a été créé, libérer la ressource † Récupération du GC avec l’écouteur PaintListener myComponent.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { event.gc.setBackground(...); } }); Le GC n’est pas créé mais récupéré du Control myComponent
  98. 100 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context † La construction d’un GC se fait par l’intermédiaire d’un objet Drawable (Control, Device et Image) † L’objet Canvas est spécialement conçu pour le dessin † A la différence des autres objets Control, Canvas dessine un rectangle plein d’une couleur par défaut † Possibilité de paramétrer le comportement du Canvas † SWT.NO_BACKGROUND : pas de couleur pour le fond † SWT.NO_REDRAW_SIZE : pas de dessin pour le re-dimensionnement † … GC myGC = new GC(myControlComponent); myGC.drawText(...); myGC.drawLine(...); ... myGC.dispose(); N’oubliez pas, si vous créez vous devez disposez !!!
  99. 101 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les couleurs † La couleur est définie par la classe Color † Color(Device d, RGB rgb) † Un objet RGB défini un triplet de trois composantes † RGB(int red, int green, int blue) † Possibilité de récupérer des couleurs définies par SWT par l’intermédiaire de la classe Display † getSystemColor(int color) : constantes définies dans SWT † Des méthodes pour modifier la couleur du GC † setBackground(Color color) : Modification de la couleur de fond pour les opérations de remplissage et pour le fond du texte † setForeground(Color color) : modification de la couleur de dessin et pour la couleur d’écriture du texte † setAlpha(int alpha) : modification de l’opacité (alpha) de la couleur (0 transparent, 255 opaque)
  100. 102 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les couleurs † Exemple : création, récupération, utilisation et libération de couleurs ... myCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { Color myColor = new Color(Display.getDefault(), new RGB(200,212,123)); event.gc.setBackground(myColor); event.gc.setAlpha(100); event.gc.fillRectangle(0,0,200,200); event.gc.setForeground(Display.getSystemColor(SWT.COLOR_BLUE)); event.gc.drawText("Message à afficher", 20, 20, true); myColor.dispose(); } } ... Le texte sera affiché sur fond transparent L’objet Color myColor doit être disposé Récupéré donc ne pas disposer ColorGraphicContextExample.java du projet GraphicExamples
  101. 103 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les formes † Dessine de points, lignes, poly-lignes, rectangles, polygones, ellipses, arcs, … † drawXXX(…) : dessine une forme XXX † Dessine des formes pleines comme des rectangles, ellipses, arcs, … † fillXXX(…) : dessine une forme pleine XXX † Modification des caractéristiques d’une ligne † setLineStyle(int style) : modification du style de la ligne † setLineWidth(int style) : modification de la taille de la ligne † Modification de la zone utilisée pour l’affichage (clipping) † setClipping(Rectangle p) : définition d’une zone par un Rectangle (également un Path ou une Region)
  102. 104 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les formes † Exemple : dessiner des formes ... myCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { event.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE)); event.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_CYAN)); event.gc.drawRectangle(0, 0, 150, 100); event.gc.setLineStyle(SWT.LINE_DASHDOT); event.gc.setLineWidth(20); event.gc.drawOval(10, 10, 160, 110); event.gc.setAlpha(150); event.gc.fillRectangle(20, 20, 250, 150); } }); ... Modification de l’aspect de transparence ShapeGraphicContextExample.java du projet GraphicExamples
  103. 105 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † Graphical Context offre la possibilité de dessiner du texte † Différentes méthodes † drawString(String p, int x, int y) : écrit le texte p à la position x et y † drawString(String p, int, int y, boolean transp) : idem avec la possibilité de forcer la transparence du fond du texte † drawText(String t, int x, int y) : idem avec la gestion de la tabulation \t, du retour à la ligne \n et d’un caractère mnemonic & † drawText(String t, int x, int y, int flags) : idem au précédent avec gestion des caractères † Gestion des caractères † SWT.DRAW_DELIMITER : gère le retour à la ligne \n † SWT.DRAW_TAB : gère la tabulation \t † SWT.DRAW_MNEMONIC : gère le caractère mnemonic & † SWT.DRAW_TRANSPARENT : fond transparent
  104. 106 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † Exemple : écrire du texte ... final String maChaine = "Voici un texte \n utilisé par deux \t\t méthodes"; myCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { event.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE)); event.gc.drawString(maChaine, 0, 20); event.gc.drawText(maChaine, 0, 40, SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_DELIMITER) ; } }); ... Tabulation non prise en compte pour le drawString TextGraphicContextExample.java du projet GraphicExamples
  105. 107 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † Des méthodes pour retourner et modifier une fonte † setFont(Font myFont) : modifie la fonte courante du GC † Font getFont() : retourne la fonte courante du GC † Un objet Font peut être construit à partir † public Font(Device device, String name, int height, int style) : construit une fonte à partir d’une police name, d’une hauteur height et d’un style style † public Font(Device device, FontData fd) : construit une fonte à partir d’un Device et d’un FontData (voir ci-après) † La création d’un objet Font implique la création d’un objet natif, donc si vous en créez un vous devrez le disposer † Il existe une fonte par défaut utilisée par le GC si aucune fonte n’est explicité Display.getSystemFont()
  106. 108 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † Un objet FontData peut être vu comme une structure de données des caractéristiques d’un objet Font † FontData(String pvaleur, int height, int sty) : police pvaleur, une hauteur height et un style sty † Un objet FontData est un objet manipulant une ressource du système et peut être disposé (automatiquement disposé si construit à partir d’un objet Font) † Différentes méthodes : † int getHeight() : retourne la hauteur de la police de caractères † setHeight(int height) : modifie la hauteur † String getName() : retourne le nom de la police † setName(String name) : modifie le nom de la police
  107. 109 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes bonjour † Les données de FontData ne permettent pas de connaître les différentes hauteur d’une police au cours du dessin † Nécessite l’utilisation du FontMetrics qui ne peut être construit, mais est accessible via le GC † FontMetrics getFontMetrics() : extraction des hauteurs d’une fonte † Les différentes hauteurs d’une fonte † int getAscent() : hauteur du corps † int getDescent() : hauteur du pied † int getLeading() : hauteur de la tête † int getHeight() : hauteur de la fonte Leading Ascent Descent Height
  108. 110 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † En complément à l’objet FontMetrics, le Graphical Context fournit des méthodes pour déterminer l’occupation pour une chaîne de texte † Différentes méthodes † Point stringExtent(String value) : retourne la largeur et la hauteur occupées par la chaîne de caractères définie par value † Point textExtent(String value) : idem en tenant compte des caractères spécifiques \t, \n et & † Point textExtent(String value, int flags) : idem en configurant les caractères spécifiques à prendre en compte Ne confondez pas la hauteur d’une fonte et la hauteur d’un texte dessiné. Il s’agit de deux valeurs différentes. Pour la seconde, la valeur dépend de la police, du style, …
  109. 111 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les textes † Exemple : respecter la dimension d’un texte ... final String maChaine = "Voici un texte \n utilisé par deux \t\t méthodes"; myCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { event.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE)); event.gc.drawString(maChaine, 0, 20); event.gc.drawText(maChaine, 0, 40, SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_DELIMITER) ; Point maChainePoint = event.gc.textExtent(maChaine); event.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); event.gc.drawRectangle(0, 40, maChainePoint.x, maChainePoint.y); } }); ... TextSizeGraphicContextExample.java du projet GraphicExamples
  110. 112 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Possibilité de charger des images à partir d’un fichier sur le disque (GIF, PNG, JPEG, TIFF, ICO, BMP et RLE) † Possibilité de créer une image pour dessiner dessus † Une image est encapsulée par la classe Image. Si vous créez un objet Image vous devrez disposer l’objet † Différents constructeurs † Image(Device device, String filename) : construit une Image à partir d’un fichier (chemin absolu) † Image(Device device, InputStream stream) : à partir d’un flux † Image(Device device, int width, int height) : vide avec une taille † Image(Device device, Image source, int flat) : à partir d’un autre objet Image † Image(Device device, ImageData data) : à partir d’un ImageData
  111. 113 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Exemple : création d’un objet Image à partir d’un fichier ... Image image1 = new Image(Display.getDefault(), "D:/Documents Mickey/Java/GraphicsExamples/example.jpg"); Image image2 = null; try { image2 = new Image(Display.getDefault(), new FileInputStream("D:/Documents Mickey/Java/GraphicsExamples/example.jpg")); } catch(FileNotFoundException e) { e.printStackTrace(); } Image image3 = new Image(Display.getDefault(), CreateImageExample.class.getResourceAsStream("/example.jpg")); new Label(shell, SWT.NONE).setImage(image1); new Label(shell, SWT.NONE).setImage(image2); new Label(shell, SWT.NONE).setImage(image3); ... Images ajoutées directement dans un Label, on verra dans la suite comment dessiner une image dans le GC CreateImageExample.java du projet GraphicExamples
  112. 114 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Exemple : copie d’un objet Image ... final Image image = new Image(Display.getDefault(), CreateImageExample.class.getResourceAsStream("/example.jpg")); Image copyImage = new Image(Display.getDefault(), image, SWT.IMAGE_COPY); Image disableImage = new Image(Display.getDefault(), image, SWT.IMAGE_DISABLE); Image grayImage = new Image(Display.getDefault(), image, SWT.IMAGE_GRAY); new Label(shell, SWT.NONE).setImage(copyImage); new Label(shell, SWT.NONE).setImage(disableImage); new Label(shell, SWT.NONE).setImage(grayImage); ... Flag qui indique comment effectué la copie (3 valeurs disponibles) CopyImageExample.java du projet GraphicExamples
  113. 115 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Dessiner un objet Image dans le Graphical Context est obtenu par deux méthodes † drawImage(Image image, int x, int y) : dessine une image à la position x et y † drawImage(Image image, int sX, int sY, int sWidth, int sHeight, int dX, int dY, int dWidth, int dHeight) : dessine une partie d’image définie par sX, sY, sWidth, sHeight à la position dX et dY avec une taille dWidth et dHeight † Dessiner avec un agrandissement … ... myCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent event) { Image myImage = new Image(Display.getDefault(),200,200); GC gc = new GC(myImage); gc.drawString("Bonjour tout le monde", 0, 0, true); event.gc.drawImage(myImage, 0, 0,200,200,0,0,500,500); event.gc.drawString("Bonjour tout le monde", 0, 50, true); gc.dispose(); myImage.dispose(); } }); ... Dessine tout d’abord sur l’image puis colle l’image dans le GC du Canvas ScaleTextExample.java du projet GraphicExamples
  114. 116 SWT - M. Baron - Page mickael-baron.fr mickaelbaron †

    Les données d’une image sont stockées dans un ImageData † byte[] data : les pixels d’une image † int alpha : la transparence † byte[] alphaData : l’alpha pour chaque pixel † int depth : le poids d’un pixel † int height, width : les dimensions d’une image † int type (SWT.IMAGE_UNDEFINED, SWT.IMAGE_BMP, …) : le format † … † Les données sont indépendantes du Device (peut être l’écran ou l’imprimante) † Constructeurs d’un ImageData † ImageData(String filename) : construit à partir d’un nom de fichier † ImageData(InputStream filename) : construit à partir d’un stream † ImageData(int width, int height, int depth, PaletteData p) : à partir d’une taille, profondeur et un palette Dessiner avec Graphical Context : les images
  115. 117 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Différentes méthodes pour manipuler ImageData † int getPixel(int x, int y) : retourne la valeur du pixel à x et y † void setPixel(int x, int y, int pixel) : modifie la valeur du pixel x et y † int getAlpha(int x, int y) : retourne l’alpha du pixel x et y † setAlpha(int x, int y, int alpha) : modifie l’alpha du pixel x et y † ImageData scaledTo(int w, int h) : retourne une nouvelle image de taille différente (grossie ou réduite) † … † Principe pour afficher un ImageData modifié † Modifier un ImageData (setPixel, setAlpha, …) † Créer un objet Image associé à l’ImageData † Pour chaque modification de l’ImageData, créer obligatoirement un objet Image pour afficher Si vous créez un objet Image, n’oubliez pas de le disposer si vous ne l’utilisez plus
  116. 118 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : les images † Exemple : un effet de transparence ... Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); shell.setText("ImagaDataAlphaColorExample"); ImageData data = new ImageData("example.jpg"); for (int i = 0; i < data.width; i++) { for (int j = 0; j < data.height; j++) { data.setPixel(i, j, (data.getPixel(i, j) + 110) % 255); data.setAlpha(i, j, (data.height - j) % 254); } } image = new Image(display, data); new Label(shell, SWT.NONE).setImage(image); ... L’ImageData est modifié, obligation de créer un objet Image pour afficher les modifications ImageDataAlphaColorExample.java du projet GraphicExamples
  117. 119 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : Transform † Possibilité d’appliquer des matrices de transformations sur un Graphical Context en utilisant la classe Transform † Fournit un ensemble de méthode pour effectuer † Des translations translate(float offsetX, float offsetY) † Des agrandissements scale(float scaleX, float scaleY) † Des rotations rotate(float angle) † Des transformations complexes setElements(…)
  118. 120 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : Transform † Exemple : un effet de réflection (inspiré de Daniel Spiewak) final Display display = Display.getDefault(); final Shell shell = new Shell(display, SWT.SHELL_TRIM ); final Image image = new Image(display, ReflectionExample.class.getResourceAsStream(/logo.bmp)); shell.setText("Reflection"); shell.setSize(300, 200); shell.setLayout(new FillLayout()); Canvas baseCanvas = new Canvas(shell, SWT.DOUBLE_BUFFERED); baseCanvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { // La suite dans le prochain transparent } }); ... ReflectionExample.java du projet TransformExamples
  119. 121 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Dessiner

    avec Graphical Context : Transform † Exemple (suite) : un effet de réflection (Daniel Spiewak) Pattern pattern = new Pattern(display, 0, 0, 0, e.height, display.getSystemColor(SWT.COLOR_GRAY), display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setBackgroundPattern(pattern); e.gc.fillRectangle(e.x, e.y, e.width, e.height); int posX = (e.width - image.getImageData().width) / 2; int posY = 10; e.gc.drawImage(image, posX, posY); Transform transform = new Transform(e.gc.getDevice()); int primaryHeight = image.getImageData().height + 10; transform.setElements(1, 0, 0, -.5f, 0, primaryHeight + (primaryHeight / 2)); e.gc.setAlpha(100); e.gc.setTransform(transform); e.gc.drawImage(image, posX, posY); transform.dispose(); pattern.dispose(); ReflectionExample.java du projet TransformExamples
  120. 122 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue † SWT fournit des classes (wrapper) pour la gestion des boîtes à outils classiques † Boîte de messages † Boîte de sélection de couleur † Boîte de sélection de répertoire † Boîte de gestion de fichier † Boîte de sélection de fonte † Boîte pour l’impression † Le style de modalité pour les boîtes de dialogue pré-définies sont obligatoirement modales † Possibilité de créer sa propre boîte de dialogue en dérivant de la classe Dialog Ne dérivez pas des classes fournissant les boîtes de dialogue communes
  121. 123 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue Boîte de messages Boîte de sélection de couleur Boîte de sélection de répertoires
  122. 124 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue Boîte de sélection de fichiers Boîte de sélection de fontes
  123. 125 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : message † Une boîte de message contient quatre éléments modifiables † Le texte dans la barre des titres † Le message à afficher dans la boîte † L’icône précisant l’importance du message † Les types de boutons pour fermer la boîte † Construction d’une boîte message par la classe MessageBox † MessageBox(Shell s, int type) : boite de message avec un style † Styles d’importance : ICON_ERROR, ICON_INFORMATION, ICON_QUESTION, ICON_WARNING, ICON_WORKING † Styles de bouton : OK, CANCEL, YES, NO, RETRY, IGNORE † Différentes méthodes … † setText(String t) : modifie le titre dans la barre † int open() : affiche et retourne le code du bouton sélectionné † setMessage(String t) : message à afficher
  124. 126 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : message † Exemple : afficher une boîte de dialogue message public class MessageDialogExample { ... public MessageDialogExample(Shell shell) { ... MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); mb.setMessage("Voulez-vous apprendre SWT?"); mb.setText("Question à 2 sous"); int value = mb.open(); if (value == SWT.YES) { System.out.println("Yes"); } else if (value == SWT.NO) { System.out.println("No"); } else { System.out.println("Cancel"); } ... } } Pas de logique dans les noms des méthodes !! Pourquoi setText(…) pour modifier le titre d’une fenêtre???? MessageDialogExample.java du projet DialogExamples
  125. 127 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de couleur † Affiche un spectre des couleurs pour en choisir une † Construction d’une boîte de couleur par la classe ColorDialog † ColorDialog(Shell s) : construit une boîte associée au Shell s † Cette boîte manipule (pour la sélection utilisateur) un objet composantes couleurs de classe RGB † RGB(int red, int green, int blue) † Objet couleur défini par la classe Color † Color(Device d, RGB rgb) † Différentes méthodes … † RGB getRGB() : retourne la couleur sélectionnée (NULL si pas de sélection) † setRGB(RGB rgb) : sélectionne une couleur pour l’ouverture † RGB open() : affiche et retourne la couleur sélectionnée † setText(String p) : modifie le titre
  126. 128 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de couleur † Exemple : afficher une boîte de sélection de couleur public class ColorDialogExample { ... public ColorDialogExample(shell shell) { ... ColorDialog cd = new ColorDialog(shell); cd.setText("Choisir une couleur"); RGB value = cd.open(); Color colorBackGround = new Color(shell.getDisplay(), value); myButton.setBackground(colorBackGround); colorBackGround.dispose(); ... } } ColorDialogExample.java du projet DialogExamples
  127. 129 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de répertoire † Cette boîte permet la sélection d’un répertoire avec possibilité d’en créer un s’il n’existe pas † Construction d’une boîte de sélection de répertoire par la classe DirectoryDialog † DirectoryDialog(Shell s) : construit une boîte associé à s † Différentes méthodes … † String getFilterPath() : retourne le répertoire sélectionné † setMessage(String p) : modifie le message contenu dans la boîte † setText(String p) : modifie le message de la barre des titres † String open() : affiche la boîte et retourne le répertoire sélectionné
  128. 130 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de répertoire † Exemple : afficher une boîte de sélection de répertoire public class DirectoryDialogExample { ... public DirectoryDialogExample() { ... DirectoryDialog dd = new DirectoryDialog(shell); dd.setText("Choisir un répertoire"); dd.setMessage("Veuillez sélectionner un répertoire"); String value = mb.open(); System.out.println(value); ... } } DirectoryDialogExample.java du projet DialogExamples
  129. 131 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : gestion de fichier † Cette boîte permet la sélection d’un fichier pour l’ouverture et la sauvegarde † Le style permet de paramétrer une boîte d’ouverture ou de sauvegarde † OPEN : pour l’ouverture d’un fichier † MULTI : pour l’ouverture de plusieurs fichiers † SAVE : pour la sauvegarde d’un fichier † Construction d’une boîte par la classe FileDialog † FileDialog(Shell s) : construit une boîte associé à s † FileDialog(Shell s, int ps) : construit une boîte avec le style ps
  130. 132 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : gestion de fichier † Différentes méthodes … † String getFileName() : retourne le fichier traité † String[] getFileName() : retourne les fichiers (pour le style MULTI) † String open() : affiche la boîte et retourne le fichier traité † setText(String p) : modifie le titre de la boîte de gestion de fichier † Possibilité de filtrer les fichiers qui apparaîtront dans la boîte † setFilterNames(String[] names) : description des noms de filtres † setFilterExtensions(String[] ex) : description des filtres † Exemples manipulation des filtres openSaveDialog.setFilterNames(new String[] { "Image BMP (*.bmp)", "Image JPG (*.jpg)" }); openSaveDialog.setFilterExtensions(new String[] { "*.bmp", "*.jpg" }); Définition des noms de filtres Définition des filtres
  131. 133 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : gestion de fichier † Exemple : afficher une boîte de gestion de fichiers public class FileDialogExample { ... public FileDialogExample() { ... Filedialog fd = new Filedialog(shell, SWT.OPEN); fd.setFilterNames(new String[] { "Image BMP (*.bmp)", "Image JPG (*.jpg)" }); fd.setFilterExtensions(new String[] { "*.bmp", "*.jpg" }); fd.setText("Choisir un fichier"); String value = fd.open(); System.out.println(value); ... } } FileDialogExample.java du projet DialogExamples
  132. 134 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de fonte † Cette boîte permet la sélection d’une fonte † Construction d’une boîte par la classe FontDialog † FontDialog(Shell s) : construit une boîte associé à s † Cette boîte manipule (pour la sélection utilisateur) un objet de classe FontData pour manipuler une fonte † La couleur de la fonte n’est pas stockée dans FontData et par conséquent la boîte retourne un objet RGB † Différentes méthodes … † FontData[] getFontList() : contient la liste des données d’une fonte † setFontList(FontData[] p) : modifie les informations d’une fonte † FontData open() : affiche la boîte et retourne la fonte † RGB getRGB() : retourne la couleur sélectionnée † setText(String t) : modifie le titre de la boîte
  133. 135 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Les

    boîtes de dialogue : sélection de fonte † Exemple : afficher une boîte de sélection de fonte public class FontDialogExample { ... public FontDialogExample() { ... FontDialog fd = new FontDialog(shell); fd.setText("Choisir une fonte"); FontData value = fd.open(); // Affichie le nom de la police utilisée System.out.println(value.getName()); ... } } FontDialogExample.java du projet DialogExamples
  134. 136 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Le processus créé par le Display est un processus graphique appelé UI-thread † UI-thread s’occupe de lire et dispatcher les événements issus du système d’exploitation puis d’invoquer les écouteurs associés à ces événements † Pour les traitements important à effectuer, utiliser un thread séparé (noté task-thread) au UI-thread de manière à ce que le UI-thread puisse traiter les événements du système † Seul le UI-thread peut manipuler les éléments graphiques et tout accès à l’extérieur du UI-thread engendre une exception de type : org.eclipse.swt.SWTException
  135. 137 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Pour résoudre le problème de SWTException il faut inclure les appels graphiques dans le UI-thread † Display fournit deux méthodes † syncExec(Runnable r) : appel synchrone † asyncExec(Runnable r) : appel asynchrone † Runnable est un objet thread en charge de la modification graphique contenant une méthode run() † void run() { code qui modifie l’IHM } † Avec un appel synchrone task-thread est en attente tant que le code contenu dans le run n’est pas terminé † Avec un appel asynchrone task-thread continue à s’exécuter en parallèle du code contenu dans le run
  136. 138 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Deux exemples qui présentent un appel synchrone et un appel asynchrone † Exemple pour l’appel synchrone † Un Thread en charge de gérer un compteur (3 à 0) † A chaque occurrence une boîte de message est lancée de manière synchrone † Tant que la boîte de message n’est pas fermé le thread compteur est bloqué † Exemple pour l’appel asynchrone † Un Thread qui gère un compteur (100 à 0) † A chaque occurrence une barre de progression est avertie de manière asynchrone † La modification de la barre de progression n’influence pas le compteur (l’IHM ne bloque pas le modèle)
  137. 139 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Exemple : affichage d’une boîte de dialogue pour un appel synchrone public class SynchroneExample { private Timer t; public SynchroneExample() { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout(SWT.VERTICAL)); Button myButton = new Button(shell, SWT.FLAT); myButton.setText("Go"); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (t != null) { t.cancel(); } t = new Timer(); t.schedule(new TimerTask() { // Voir transparent suivant ... }, 0, 1*1000); } }); ... } ... } SynchroneExample.java du projet DialogExamples
  138. 140 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Exemple (suite): affichage d’une boîte de dialogue pour un appel synchrone t.schedule(new TimerTask() { int nbrRepetitions = 3; public void run() { if (nbrRepetitions > 0) { System.out.println("Ca bosse dur!"); nbrRepetitions--; display.syncExec(new Runnable() { public void run() { MessageBox d = new MessageBox(shell, SWT.YES); d.setText("Mon Titre"); d.setMessage(""); d.open(); } }); System.out.println("Ici"); } else { System.out.println("Terminé!"); t.cancel(); } } }, 0, 1*1000);
  139. 141 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Exemple : barre de progression pour un appel asynchrone public class ASynchroneExample { private Timer t; public ASynchroneExample() { ... Button myButton = new Button(shell, SWT.FLAT); final ProgressBar myProgressBar = new ProgressBar(shell, SWT.NONE); myProgressBar.setMaximum(100); myProgressBar.setMinimum(0); myProgressBar.setSelection(100); myButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (t != null) { t.cancel(); } t = new Timer(); t.schedule(new TimerTask() { // Voir transparent suivant ... }, 0, 1 * 10); } }); ... } ... } ASynchroneExample.java du projet DialogExamples
  140. 142 SWT - M. Baron - Page mickael-baron.fr mickaelbaron UI-thread

    et SWTException † Exemple (suite) : barre de progression pour un appel asynchrone t.schedule(new TimerTask() { int nbrRepetitions = 100; public void run() { display.asyncExec(new Runnable(){ public void run() { myProgressBar.setSelection(nbrRepetitions); } }); if (nbrRepetitions > 0) { nbrRepetitions--; } else { System.out.println("Terminé"); t.cancel(); } } }, 0, 1 * 10); ASynchroneExample.java du projet DialogExamples
  141. 143 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † L’API SWT permet d’intégrer des composants basés sur la boîte à outils Swing † L’avantage est de pouvoir intégrer des composants qui n’existe pas dans la boîte à outils SWT † L’inconvénient est de se trouver avec des composants hétérogènes dans la manière de les utiliser † Abonnement à des écouteurs différents † Gestion du « dessin » différent † Agents de placement différents † Bref beaucoup de différences Evitez tant que possible de mixer des composants Swing avec SWT
  142. 144 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Exemple : intégrer des composants JFreeCharts et JGraph JGraph JFreeCharts
  143. 145 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † L’intégration de composants Swing se fait par l’intermédiaire de la couche bas niveau de Swing c’est-à-dire via AWT † Principe général † Le point d’entrée de Swing vers SWT est obtenu par l’intermédiaire d’une Frame (java.awt.frame) † Tous composants Swing doit être contenus dans une Frame (ou plusieurs) † Il faut voir la Frame comme un conteneur au même titre que le Composite en SWT † L’handle de la Frame (identifiant) est récupéré puis utilisé par SWT pour ajouter le contenu de la Frame vers un Composite SWT Exemple : il est possible d’intégrer n’importe quelle application Win32 dans du SWT par l’intermédiaire des handles de fenêtre : à suivre …
  144. 146 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † L’API SWT fournit une API spécifique pour l’intégration de composants Swing † package : org.eclipse.swt.awt † classe : SWT_AWT † Les méthodes de la classe SWT_AWT † static Frame new_Frame(Composite parent) : construit une Frame contenant les composants Swing, parent est le conteneur SWT qui contiendra la Frame créée † La Frame créée est la racine des composants Swing † Le Composite parent doit avoir le style SWT.EMBEDDED
  145. 147 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Exemple : SWT + Swing = SWingT ? public class SWTAWTExample { ... public SWTAWTExample() { Display display = new Display(); Shell shell = new Shell(display); GridLayout layout = new GridLayout(1, false); shell.setLayout(layout); shell.setText("SWT and Swing/AWT Example"); Label separator1 = new Label(shell, SWT.NONE); separator1.setText("Mon Message en SWT"); Composite awtComp = new Composite(shell,SWT.EMBEDDED); GridData myGridData = new GridData(GridData.FILL_BOTH); awtComp.setLayoutData(myGridData); Frame awtFrame = SWT_AWT.new_Frame(awtComp); JTextField textField = new JTextField("Saisir une valeur dans du Swing"); awtFrame.add(textField); ... } } Composant Swing Composant SWT SWTAWTExample.java du projet SWTAndSwingEamples
  146. 148 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Exemple : Winrar dans une Shell † Utilisation de la classe org.eclipse.swt.internal.win32.OS Shell SWT Button SWT Application WINRAR Peut très bien être du natif MAC OS, Linux, …
  147. 149 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Une des grandes forces de la boîte à outils Swing concerne l’API Java 2D † Le portage de composants Swing vers SWT reste facile, mais qu’en est-il d’un code Java 2D à migrer ou adapter ? † Une solution est fournie par la classe Graphics2DRenderer † www-128.ibm.com/developerworks/java/library/j-2dswt/ † Principe † Construire un objet Graphics2DRenderer † Récupérer le GC d’un composant SWT (par exemple un Canvas) † Initialiser l’objet Graphics2DRenderer avec le GC † Utiliser l’API Java2D de Sun † Générer un rendu des opérations Java2D dans le GC par l’intermédiaire du Graphics2DRenderer
  148. 150 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Principe de fonctionnement de Graphics2DRenderer
  149. 151 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT † Une autre façon de faire cohabiter des composants Swing est d’utiliser la librairie SwingWT † SwingWT fournit une re-implémentation des composants Swing en SWT † Adresse : swingwt.sourceforge.net † La logique de l’API Swing est respectée † javax.swing.JButton en Swing † swingwt.swing.JButton en SwingWT † Avantages † Fournir des plug-ins Eclipse en utilisant les composants types Swing † Refactoring très facile d’anciennes applications Swing † Compilation en code natif avec GCJ † Inconvénients † Retard par rapport aux nouveautés des JDK
  150. 152 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Cohabitation

    entre composants Swing et SWT Demo SwingSet en utilisant SwintWT (refactoring immédiat de l’application)
  151. 153 SWT - M. Baron - Page mickael-baron.fr mickaelbaron Bilan

    … † Premières impressions … † Pas aussi souple que Swing (limitée par rapport au système hôte) † Difficile de réaliser des effets graphiques (absence de GlassPane :-( ) † Venant du monde Swing la tentation d’incorporer des composants Swing dans du SWT est forte (SWT pas aussi fournie en composant) † Sur le net, peu de « hacker » SWT ;-) † Parfois, l’API SWT n’est pas un modèle de programmation !!! † Les choses non étudiées, prochainement … † La gestion de l’impression † Approfondir Graphical Context (Transformation [scale, rotate, …]) † Appels à des fonctions systèmes via JNI/JNA et la classe OS † …