Déménagement de tout le contenu vers le site:
http://www.while-true-do.com
Les articles ont été rénovés et de nouveaux ont été ajoutés.
Développement logiciel & programmation, concepts mécanismes & techniques
Mises en oeuvre en langages C# et Java
| Février 2012 | ||||||||||
| L | M | M | J | V | S | D | ||||
| 1 | 2 | 3 | 4 | 5 | ||||||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 | ||||
| 13 | 14 | 15 | 16 | 17 | 18 | 19 | ||||
| 20 | 21 | 22 | 23 | 24 | 25 | 26 | ||||
| 27 | 28 | 29 | ||||||||
|
||||||||||
Déménagement de tout le contenu vers le site:
http://www.while-true-do.com
Les articles ont été rénovés et de nouveaux ont été ajoutés.
Mise à jour, déménagement de tout le contenu vers le site:
http://www.while-true-do.com
Les articles ont été rénovés et de nouveaux ont été ajoutés.
1. Objectif
Cet article concerne le codage d’une confirmation demandée à l’utilisateur avant de quitter une application Windows classique à base de formulaires en C# (WinForms). Il est possible de quitter l’application de plusieurs manières : (1) Activer l’option de menu, (2) appuyer sur un bouton, (3) cliquer sur X en haut à gauche de la fenêtre Windows ou enfin (4) appuyer sur les touches Alt-F4.
|
//-----------------------------------------------------------
// demande au user confirmation pour quitter,
// renvoie true si confirmé
private bool AskConfirmQuitAppli()
{
// message confirmation quitter l'application
if(MessageBox.Show("Quitter l'application?",
"Message de confirmation" , MessageBoxButtons.YesNo) == DialogResult.No)
{
// non
return false;
};
// oui, quitter
return true;
}
//-----------------------------------------------------------
// event déclenchée par Close()
// déclenche ensuite event Closed sauf si annulé
private void MainForm_Closing(
object sender, System.ComponentModel.CancelEventArgs e)
{
//non confirmé, opération annulée, ne déclenche pas event Closed
if(AskConfirmQuitAppli()==false)
e.Cancel= true;
}
//-----------------------------------------------------------
// bouton 'quitter'
private void button1_Click(object sender, System.EventArgs e)
{
// déclenche closing (demande de confirmation)
Close();
}
//-----------------------------------------------------------
// menu 'quitter'
private void menuItem3_Click(object sender, System.EventArgs e)
{
// déclenche closing (demande de confirmation)
Close();
}
|
4. Bibliographie
http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfSystemWindowsFormsFormClassClosingTopic.asp
Aide MSND, évènement Closing
Mise à jour, déménagement de tout le contenu vers le site: Les articles ont été rénovés et de nouveaux ont été ajoutés.
http://www.while-true-do.com
1. Les itérateurs: concepts
Un itérateur est une sorte de curseur dont le travail est de se déplacer dans une séquence d’objets, d’offrir un accès simple à chaque objet de cette séquence sans se préoccuper de la structure de stockage sous-jacente. De plus, un itérateur est un objet peu coûteux en espace mémoire et rapide à créer et à détruire. 1.2. Types d'itérateurs On peut classifier les itérateurs selon le sens possible de déplacement : -Itérateurs Bi-directionnel : Mais aussi selon le mode d’accès aux données : 1.3. Importance des itérateurs 1/ parcours standard et uniforme 2/ faciliter l’itération des séquences Et avoir même un fonctionnement complexe : 3/ itérations multiples sur un même containeur 4/ Couplage « faible » entre code itérateur et le code du containeur 1.4. Stratégie de fonctionnement
L’itérateur est fournit (fabriqué) par la collection elle-même. Deux méthodes suffisent pour gérer l’itérateur. Une première méthode indique s’il existe un élément suivant et renvoie vrai dans ce cas là. Une autre méthode qui se déplace sur l’élément suivant et le renvoi. 2. Les itérateurs en Java En Java, le conteneur en séquence standard est le ArrayList depuis la version 1.2 de Java (plutôt que Vector). Simple et facile à mettre en œuvre, il est largement suffisant pour un usage général de stockage d’objets. 2.2. Itérateurs sur collection en Java Le comportement d’une liste d’éléments est modélisé par une interface : List. Cette interface dispose de toutes sortes de méthodes pour offrir les fonctionnalités d’une liste: ajout, suppression d’éléments,…. L’itérateur standard sur les listes est défini par l’interface Iterator dont l’interface List dispose d’un membre. La classe ArrayList hérite de la classe abstraite Abstract List et met en œuvre l’interface List. L’utilisation d’une liste (ArrayList) et d’un itérateur associé (ou plusieurs si nécessaire) se fait simplement en créant un objet ArrayList et en lui ajoutant des éléments. Ensuite, pour parcourir les éléments, une demande est faite à la liste pour qu’elle fabrique un (ou plusieurs) itérateur sur les éléments qu’elle contient. Cet itérateur sera instancié et positionné automatiquement sur le début de la liste. Exemple de parcours avec itérateur
// remplir la liste d’éléments // demande un itérateur au conteneur // tant qu’il un élément suivant dans la collection Ou dans une version simplifiée plus concise pour le parcours des éléments, possible depuis java 1.5 :
3. Les itérateurs en .NET/C# 3.2. Itérateurs sur une collection en C# La forme très concise de type foreach pour parcourir les collections existe en standard dans .NET :
// parcours la liste des objets, les affiche
1.1. présentation des itérateurs
Les itérateurs servent à parcourir les conteneurs –appelés aussi collections- de type séquence comme les vecteurs, liste, piles, files, ou autres. Pour le tableau, l’itérateur est simplement un indice qui accède aux éléments via l’opérateur [].
Les bibliothèques de certains langages poussent très loin le concept d’itérateurs comme la STL (Standart template Library) de C++. Les environnements de dernière génération comme Java ou .NET ne sont pas en reste, ils proposent en standard de nombreuses collections et différents types d’itérateurs pour les parcourir.
-Itérateurs unidirectionnels :
Déplacement en avant, c’est le plus standard.
Déplacement en arrière.
Déplacement avant-arrière
-Itérateurs en lecture seule
-Itérateurs en en lecture/Ecriture
Le mécanisme des itérateurs offre de nombreux avantages aux programmeurs :
Par un niveau d’abstraction élevé, les itérateurs fonctionnent de la même manière quel que soit le conteneur, (et même quel que soit le langage de programmation). Cela réduit d’autant l’apprentissage des itérateurs et donc la maintenance des programmes.
Avec quelques méthodes, parcourir simplement une séquence d’éléments.
itérateurs bi-directionnels,
insertion/suppression durant une itération,…
C’est un avantage fonctionnel certain comparé à des méthodes basiques qui ne permettent pas (ou difficilement) de multiples itérations sur un containeur.
On sépare (dans la mesure du possible) le code d’itération du code de la classe containeur.
La mise en œuvre des itérateurs se veut la plus simple possible. Le fonctionnement des itérateurs a été défini par le pattern d’itération. Ce pattern repris notamment dans le langage Java précise que l’itérateur est un curseur qui désigne une position, avant ou après un élément. A la création de l’itérateur, celui-ci est positionné avant le premier élément de la collection.
2.1. Les collections en Java
Java dispose de base d’un riche ensemble de collections –les Java Collections Framework- définis par de nombreuses classes et interfaces. Cet ensemble a été remis à neuf depuis la version 1.2 avec l’introduction de plusieurs interfaces pour « abstraire » les conteneurs comme la liste. Les collections ont été unifiées et simplifiées autour de quelques classes et interfaces essentielles. La version 1.5 de Java a apporté la généricité (les templates) et une syntaxe simplifiée (de type foreach) pour le parcours des collections.
Java met à disposition un itérateur standard basique (classe Iterator) pour parcourir les éléments d’une collection (que dans un seul sens). Java propose aussi un itérateur plus élaboré (classe ListIterator) qui offre un parcours bi-directionnel du conteneur. Voyons la mise en œuvre d’un itérateur sur une collection de type ArrayList.
Soit un ensemble d’objets personnes (classe Person) stockées dans une collection ArrayList (objet persons). Les éléments sont parcourus un à un et sont affichés.
// création d’une liste d’éléments
ArrayList persons = new ArrayList();
Person p= new Person("john", "mith");
persons.add(p);
...
Iterator i = persons.iterator();
while(i.hasNext())
{
// extrait (une référence sur) l’élément suivant
Person p= (Person)i.next();
// traite l’élément extrait: l’affiche
p.print();
}
for(Person p : persons)
{
p.print();
}
3.1. Les collections
Comme en Java, .Net fourni une bibliothèque de conteneurs très riche représentés par des classes et des interfaces. Les comportements des conteneurs sont « abstraits » comme en Java et modélisé par quelques interfaces : IList pour les listes, IDictionnary pour les map.
Les itérateurs en C# fonctionne de manière identique aux itérateurs de Java. Dans .NET, une collection pouvant être parcourue par un itérateur doit mettre en œuvre l’interface IEnumerable. La classe standard pour gérer une liste d’éléments est ArrayList.
// collection d’éléments
protectedArrayList Persons= new ArrayList();
foreach(Person p in Persons)
p.Print();
4. Bibliographie
http://www.dotnetguru.org/articles/Comparatifs/JSR201/JavaVsCSharpNews.htm
Article « Java sur les traces de C# », par Sami Jaber (jaber@ifrance.com)
un paragraphe concerne les itérateurs java read-only un autre concerne le parcours des collections (simples et génériques) via l’instruction foreach.
http://java.sun.com/j2se/1.4.2/docs/guide/collections/index.html.
Documentation Java « Collections Framework », Par Sun. Page d’accueil de la documentation du framework des collections de Sun sur Java
http://java.sun.com/j2se/1.4.2/docs/guide/collections/reference.html
Documentation Java «Annotated Outline of Collections Framework », Par Sun
Liste (API) des conteneurs (classes, interfaces, classes abstraites et autres) de la documentation de Sun
http://www.pps.jussieu.fr/~rifflet/enseignements/JAVA/iterateurs.html
Article « Collections et itérateurs », Par Rifflet
Présente l’interface Iterator et ses méthodes (Java).
http://www.dotnetguru.org/articles/dossiers/iteratorcsharpv2/CS2_Iterators_FR.htm
Article « Les itérateurs de C#2 » , par Patrick Smacchia
article très pointu sur la puissance des itérateurs en .NET #2. (avec une présentation en #1).
Mise à jour, déménagement de tout le contenu vers le site: Les articles ont été rénovés et de nouveaux ont été ajoutés.
Les délégués du C# sont équivalents aux pointeurs de fonction du C/C++ mais en plus sécurisé (type-safe). En simplifiant, on peut dire qu’un délégué est un pointeur vers une méthode mais c’est bien plus que cela. Un délégué est un intermédiaire entre un émetteur et un récepteur, il permet d’établir un contrat entre eux. C’est un moyen de communication entre objets qui ne se connaissent pas forcément. Les délégués sont très utilisés dans l’environnement .NET, notamment le mécanisme de gestion des évènements qui est directement basé sur les délégués ; un évènement est d’ailleurs un délégué spécialisé.
La notion de délégué pourrait être comparé à celle d’interface puisque une interface est aussi un contrat entre classes sauf qu’un délégué n’établit son contrat qu’avec une méthode et non une classe. En quoi consiste le contrat d’un délégué? Il consiste lors de la déclaration de celui-ci à spécifier complètement une méthode: ses paramètres, leur nombre, leur type et le type de retour de la méthode.
2. Quel est l’intérêt d’utiliser un délégué ?
Ce mécanisme que les délégués utilisent de type « rappelle moi plus tard » (système de rappel, callback en Anglais) permet de gérer aisément les traitements asynchrones mais offre aussi d’autres avantages. Dans l’exemple précédent, la classe communication ne connaît rien de l’application qui l’utilise, le code de cette classe est indépendant et réutilisable dans d’autres situations sans aucune modification. De manière générale, l’utilisation des délégués permet de créer des classes, des contrôles ou composants utilisateurs indépendants les uns des autres (dit à couplage faible) ce qui facilite la réutilisation du code et tout ce qui en découle : maintenance, évolution & publication. 3. Utilisation d’un délégué ; exemple
Un délégué est un type, une signature de méthode, qu’il faut définir. Utiliser un délégué nécessite de déclarer une variable du type du délégué à utiliser. Le délégué déclaré ci-dessous défini une signature de méthode appelée DataReceived, pleinement précisée : la méthode comporte un paramètre de type chaîne de caractères, la valeur de retour est de type entier.
// le délégué, initialisé à null L’utilisation d’un délégué passe par plusieurs phases : la connexion ou l’abonnement, le déclenchement puis la notification. L’abonnement consiste à instancier le délégué et à le relier à une méthode dans la classe qui utilise l’objet ayant le délégué.
// instancie l'objet pour communiquer // instancie le délégué et le relie à une méthode de l’application Le déclenchement du délégué consiste à l’appeler comme un simple appel de méthode lorsque c’est nécessaire.
// appel si délégué est connecté La notification est le fait que le délégué déclenche automatiquement lorsqu’il est appelé la méthode associée dans l’application.
Le délégué a fait son travail d’intermédiaire, il relaye la notification à la méthode associé dans l’application. 4. Code de l’exemple Communication commenté Classe communication
// variable du type délégué donnée recue // ... //----------------------------------------------------------- // boucle d'attente // appel délégué pour signaler présence donnée recue // suite traitement ...
http://www.while-true-do.com
L’intérêt des délégués n’est pas forcément visible au premier abord. Cependant, ils répondent à un problème récurrent en programmation : Fournir un traitement via une méthode à un objet qui l’exécutera plus tard (traitement asynchrone), c'est-à-dire que l’objet appellera ce code au bon moment et ce sans forcément le connaître. Par exemple, une application exécute un objet chargé de gérer des communications via le réseau utilisera un délégué pour signaler qu’une donnée vient d’arriver et est disponible.
La classe communication est chargée de gérer les communications réseaux, d’envoyer et de recevoir des données. La réception des données est indépendante du fonctionnement de l’objet, elle ne dépend que des émetteurs. Elle sera gérée par un délégué qui sera associé à une méthode dans l’application. Cette méthode affichera la donnée reçue.
// définition d’un type délégué
delegate int DataReceivedHanlder(data);
DataReceivedHandler dataReceivedHandler=null;
comm= new Communication();
comm.dataReceivedHandler= new Communication.DataReceivedHandler(this.DonneeRecue);
// appel délégué pour signaler présence donnée recue
if( dataReceivedHandler != null)
dataReceivedHandler(data);
//-----------------------------------------------------------
// déclenché par le délégué lorsque une donnée est recue
private void DonneeRecue(string data)
{
// affiche le message recu
MessageBox.Show("donnée recue: "+data);
}
Ci-dessous, se trouve les extraits de codes principaux utilisé pour expliquer le fonctionnement des délégués.
//-----------------------------------------------------------
public class Communication
{
// déclaration type délégué
public delegate int DataReceivedHandler(string data);
public DataReceivedHandler dataReceivedHandler=null;
// traitement d'attente en réception des données
// effectué dans une boucle, exécuté par un thread
public void RunReceptionData()
{
string data= null;
while(true)
{
// donnée en reception
// ... remplir variable data
if( dataReceivedHandler != null)
dataReceivedHandler(data);
}
}
}
Application principale:
|
//-----------------------------------------------------------
//----------------------------------------------------------- |
4. Bibliographie
C# : introduction aux délégués sur JDN développeurs publié le 16 fev 2005 , 1 page
Par Xavier Borderie
Présente ce que sont les délégués de manière générale
http://developpeur.journaldunet.com/tutoriel/csharp/050216-csharp-delegate-1.shtml
« Un évènement à ne pas oublier »
Un article très intéressant qui explique de manièe claire ce que sont les délégués et les évènements en C#
Par Eric Gunnerson de Microsoft.
http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/dncscol/html/csharp04192001.asp
MSDN Les délégués, documentation technique , en français
chap 15, 15.1, 15.2 et 15.3
http://msdn.microsoft.com/library/fre/default.asp?url=/library/fre/csspec/html/vclrfcsharpspec_15.asp
C# versus Java
Article complet qui compare entre eux les caractéristiques des langages C# etJava
La partie B.14 sur les évènements aborde les délégués.
Par Alain Vizzini
http://alain.vizzini.free.fr/localcopy/csvsjava.htm
Mise à jour, déménagement de tout le contenu vers le site: Les articles ont été rénovés et de nouveaux ont été ajoutés.
http://www.while-true-do.com
1.1. espace de travail, projets et applications
Eclipse est un outil puissant, riche mais sa prise en main reste déroutante pour celui qui débute sur cet environnement. Une des premières difficultés que l'on rencontre quand on démarre l'outil est de savoir comment organiser de manière cohérente l'application Java que l'on veut développer.
Les éléments principaux d’organisation dans Eclipse sont l'espace de travail ou Workspace et le projet. Eclipse travaille toujours dans un "workspace" courant, c’est un espace de travail général, il contient des projets, un seul est actif à la fois, c'est celui sur lequel on travaille. Dans un même projet, il pourra y avoir éventuellement plusieurs applications chacune exécutée par une méthode main() différente.
Hiérarchie des éléments
Exemple d’organisation d’un espace de travail contenant plusieurs projets :
MyWorkspaceWksp
MyFirstProjectPrj
MySecondProjectPrj
Il est pratique de préfixer les éléments pour se repérer facilement dans l’environnement. Ici le espace de travail est préfixé par Wksp pour workspace, les projets sont préfixés par Prj. Les applications –représentées par une classe java contenant une méthode main- seront préfixées par App.
1.2. Le répertoire metadata
Dans chaque répertoire propre à un workspace, Eclipse génère un répertoire volumineux (6Mo au minimum) se nommant .metadata contenant les éléments de base d’Eclipse sous forme de plugs-in nécessaires au fonctionnement de l’application en cours de développement. Il permet notamment d’écrire une application cliente riche ou RCP (Rich Client Platform) utilisant l’interface graphique SWT propre à Eclipse au lieu d’utiliser AWT ou Swing.
Exemple d’organisation d’un projet séparant les fichiers sources des binaires et autres :
MyProjectPrj
src
Fichiers sources .java
bin
Fichiers compilés .class
Dans Eclipse, une fois le projet créé, pour que les sources soient stockés à part, créé un ‘source folder’
Puis ensuite créé les paquetages et classes de l’application.
Soit une application simple de démonstration qui édite les informations d’une personne ; nom, prénom, adresse,…
L’application sera structurée de la manière suivante :
3.1. Les opérations
-Créer un workspace, appelez le : MyPersonManagerWksp
-Créer un projet, appelez le : PersonEditPrj
-Créer le répertoire pour stocker les sources, nommez le : src.
-Dans le projet, créer un paquetage représentant l’application, nommez le : personEditApp avec la 1ere lettre en minuscule, par convention.
-Dans ce paquetage, créer une classe principale contenant un main, nommez la : PersonEditApp comme le paquetage, avec la 1ere lettre en majuscule, par convention.
-Créer une autre classe pour gérer une personne, nommez la Person, avec la 1ere lettre en majuscule, par convention.
Organisation d'un projet
L’application est représentée par la classe PersonEditApp qui contient une méthode main. Une autre application pourrait exister en créant une autre classe dans le même paquetage ou non. Cette autre classe devrait avoir elle aussi une méthode main ; par exemple : PersonEdit2App.