Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox
Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par Nataly, le 06 octobre 2011

Une fois l'étape interaction franchie (MouseEvent), ce qui doit être le cas si vous venez du chapitre précédent, on peut attaquer de “causer avec l'utilisateur”, j'entends par là écrire des choses à son attention, voire lire ce qu'il aura saisi et agir en conséquence.

Variables, fonctions, syntaxe
Objets, méthodes, propriétés…
Clics et événements souris sur les boutons et les clips
Champs texte et objet String (ici)
Structures de contrôle alternatives : if
MovieClip : manipuler
• Structures de contrôle alternatives : switch
• Structures de contrôle répétitives : for - while
Liste d'affichage, imbrication et profondeur des objets
Liste d'affichage, gestion dynamique des objets
Les tableaux

Champs texte et String

Pour écrire, qu'il s'agisse du développeur ou de l'utilisateur, on a recours à des objets dédiés : les champs texte (TextField).

Il nous faut donc un champ texte. Deux solutions : soit il existe déjà (on a posé un champ sur la scène ou dans un clip), soit on le crée de façon dynamique (tout en code, on verra comment s'y prendre plus tard [lien]).
Une fois le champ texte existant, on le “remplit” avec des caractères ; plus correctement exprimé on parlera de chaîne de caractères, soit - quand on passe par une variable - un type String, comme vous le savez.

TextField

Pour nous entrainer à manipuler des champs textes, je vous propose de commencer avec des champs pré-existants.
Dessinez donc sur la scène un premier champ texte à l'aide de l'outil Texte et prenez soin de préciser son type : dynamique (pour pouvoir en modifier le contenu en code) ou saisie (pour permettre à l'utilisateur d'écrire dedans).
Pendant qu'on y est on lui donne un nom - ce sera indispensable dès qu'on voudra coder - et si le cœur vous en dit, choisissez une couleur, une police, une taille, l'alignement… On peut même déjà y saisir ce qu'on veut histoire de voir quelque chose à l'exécution1).



Lecture/Ecriture : text

Pour Flash, en dessinant à l'aide de l'outil Texte un champ sur la scène on a, en fin de compte, fabriqué une instance de la classe TexteField (et on l'affichée ça semble évidant mais ce qui va sans dire…), tout comme en glissant un symbole depuis la bibliothèque, on crée une instance de MovieClip2).

Une des principales propriétés de cette classe TexteField, c'est text. Elle vaut (renvoie) une chaîne qui correspond au texte du champ de texte nous dit la doc.

En clair, pour lire ce qui y est contenu :

trace(txtDemo.text);

On peut bien sûr “stocker” le résultat “dans” une variable de type String

var leTexte:String=txtDemo.text;
trace(leTexte);



Pour écrire quelque chose dans un champ texte :

txtDemo.text="un truc pour voir";


Police partout, justice nulle part, embarquez moi tout ça !

Si vous suivez le tuto au pas à pas, que vous n'en n'avez pas plus fait que je n'en ai suggéré, et que vous testez cette dernière ligne, vous devez avoir un bien piètre résultat : une espèce de crachoti de quelques lettres : un tu u
Avec Bonjour, c'est pas mieux, ça fait : nju, sans compter que la fenêtre de sortie râle dans son coin depuis un moment :

Les polices doivent être incorporées pour tous les textes pouvant être modifiés à l'exécution, hormis pour les textes dont le paramètre “Utiliser les polices de périphérique” est activé. Utilisez la commande Texte > Incorporation de polices pour incorporer les polices.


Eh oui, le propre d'un champ texte dynamique c'est de permettre la modification de son contenu (sans quoi on aurait utilisé un champ statique ;)). Il s'agit donc d'incorporer les glyphes potentiellement utilisés. En français on parle aussi de caractères embarqués, en anglais on utilise le verbe to embed (enchâsser/encastrer dans ce contexte).

Lorsque vous lisez vos fichiers SWF publiés sur des ordinateurs connectés à Internet, il est possible que les polices que vous avez utilisées ne soient pas disponibles sur ces ordinateurs. Pour vous assurer que votre texte conserve l’apparence que vous lui avez donnée, vous pouvez incorporer des polices complètes ou uniquement certains jeux de caractères. Lorsque vous incorporez des caractères dans votre fichier SWF publié, la police est automatiquement disponible dans le fichier SWF, quel que soit l’ordinateur sur lequel vous lisez le fichier. Une fois la police incorporée, vous pouvez l'utiliser partout dans votre fichier SWF publié.
dixit la doc


Faisons donc ce qu'on nous demande : incorporons les polices, soit comme on nous le propose, soit d'un clic droit dans la partie vide de la bibliothèque en choisissant nouvelle police, soit encore à l'aide du bouton incorporer dans le panneau de propriétés d'un champ texte.

Dans le cadre de nos tests, incorporons tout ce qui pourrait être utile sans jouer la demie mesure (ce que c'est énervant de chercher vingt minutes pourquoi un bout de code ne fonctionne pas alors que c'est bêtement l'affichage qui rate les glyphes non embarqués !).

Manipuler les chaines de caractères

Concaténer

On l'a vu vite fait : concaténer, ça signifie ajouter bout à bout des chaines et ça se fait en AS3 à 'aide de l'opérateur '+' (plus). Regardons-y de plus près

trace("je concatène "+"deux chaines");// pensez à l'espace entre guillemets
 
var toto:String="bonjour";
trace("je dis "+toto);
 
var chiffre1:int=6;
var chiffre2:int=4;
var result:int=chiffre1*chiffre2;
trace(chiffre1+" que multiplie "+chiffre2+" font "+result);
je concatène deux chaines
je dis bonjour
6 que multiplie 4 font 24


Là, il y a ceux qui froncent le sourcil et remarquent que chiffre1 est de type int, alors quoi ? Concaténer ça mélange des chaines ou n'importe quoi ?
Ça mélange des chaines et quand ça rencontre autre chose ça s'en débrouille et ça renvoie de la chaine.
Par exemple pour en revenir à nos champs textes essayez :

var chiffre1:int=6;
var chiffre2:int=4;
var result:int=chiffre1*chiffre2;
 
txtDemo.text = chiffre1+" que multiplie "+chiffre2+" font "+result;

vous obtenez la phrase ds le champ texte comme attendu. Essayez plus bêtement :

txtDemo.text = chiffre1;

Et là… damnation !
Ça crie dans la fenêtre d'erreurs de compilation :

Contrainte implicite d'une valeur du type int vers un type sans rapport String.


Eh oui, la propriété text est de type String et chiffre1 de type int.



Pour en revenir à l'opérateur de concaténation, je vous disais à l'instant que si on lui passait une chaine et un autre type il s'en débrouillait et renvoyait une chaine, preuve :

txtDemo.text = chiffre1+"";


Ça passe, le champ a bien reçu de la chaine ;)

Bien sûr ce n'est qu'à titre d'illustration, quand on a besoin de convertir en chaine on utilise la fonction String :
txtDemo.text = String(chiffre1);

Les dangers de l'opérateur '+'

Soyez d'autant plus vigilants avec cette “facilité” de l'opérateur de concaténation, que c'est aussi l'opérateur d'addition, je m'explique :

var hommes:int=6;
var femmes:int=5;
 
txtDemo.text=hommes+femmes+" participants";

ici tout va bien, on récupère 11 participants ds le champ texte.
Le 'signe plus' entre deux int (variables hommes et femmes) a été compris comme opérateur d'addition, le suivant (avant la chaine participants) coincé entre un chaine et un int, convertit ce dernier en type String et nous obtenons le résultat attendu.
Sans la chaines ” participants” on est d'accord que ça aurait râlé dès la compilation3)

Imaginons maintenant que dans l'enthousiasme vous ajoutiez une chaine au début :

txtDemo.text="il y a : "+hommes+femmes+" participants";
Encastrées comme elles le sont entre deux chaines les variables hommes et femmes sont alors comprises comme chaines et nous nous retrouvons avec 65 participants !

Les caractères spéciaux

Puisque on utilise des guillemets pour signifier début et fin de chaine, comment s'y prendre pour en intégrer un caractère au sein d'une chaine ?
En le faisant précéder du caractère d'échappement\ (antislash). Ce même caractère d'échappement suivit de n (\n) crée une nouvelle ligne.

trace("Une \"pomme\" rouge\nUne autre ligne");
Une "pomme" rouge
Une autre ligne

Méthode appendText

Pour ajouter du texte à un champ texte on pourrait alors être tentés d'utiliser l'opérateur de concaténation :

txtDemo.text+="\nune deuxième ligne";
// identique à 
//txtDemo.text=txtDemo.text+"\nune deuxième ligne";


Ce qui fonctionne parfaitement, mais…
… dans le panneau d'erreurs à la compilation on nous avertit :

Warning: 3551 : L'ajout de texte à la fin d'un champ texte TextField avec += est beaucoup plus lent que l'utilisation de la méthode TextField.appendText().


Pour bénéficier des bons conseils de notre amis Flash encore faut-il avoir coché la case Mode avertissements depuis les paramètres de publication :



Qu'à cela ne tienne, si on nous le demande gentiment, allons-y donc :

txtDemo.appendText("\nune deuxième ligne");



:idea: Et si vous ne la voyez toujours pas cette deuxième ligne, c'est que vous avez oublié de cocher la case multiligne du panneau de propriétés.

Un peu d'entrainement

Si vous souhaitez vous y frotter, je vous renvoie à la fiche de synthèse en fin de tuto première page, colonne de gauche.

String

Puisque les chaines de caractères sont des objets de type String, faisons un petit tour du côté de cette classe qui expose un certain nombre de méthodes et propriétés furieusement pratiques.

Si vous posez le curseur sur le mot String quelque part dans votre code et utilisez la touche F1 vous arriverez sur la doc au chapitre concerné. Vous pouvez aussi, pour consulter la liste des méthodes et propriétés utiliser le panneau latéral de la fenêtre action.



Vous trouverez la classe String dans la catégorie Niveau supérieur4) (notez qu'un clic droit affiche un menu qui mène à l'aide) et la liste exhaustive des méthodes et propriétés qu'elle expose.

Quelques méthodes de première utilité

toUpperCase et toLowerCase

Au nombre des méthodes de recours fréquent vous pouvez noter toUpperCase et sa copine toLowerCase qui convertissent tous les caractères d'une chaine en majuscules pour la première, et en minuscules pour la seconde.

var c:String = "Une Chaine Avec Des MAJUSCULES et des minuscules";
var maj:String = c.toUpperCase();
var min:String = c.toLowerCase();
trace(maj);
trace(min);
trace(c);// On est bien d'accord que la chaine d'origine n'est pas modifiée


UNE CHAINE AVEC DES MAJUSCULES ET DES MINUSCULES
une chaine avec des majuscules et des minuscules
Une Chaine Avec Des MAJUSCULES et des minuscules

substr

Renvoie une sous-chaîne dont le premier caractère est précisé par le premier paramètre, et le nombre de caractères total précisé par le deuxième paramètre.

Prenez garde : le premier caractère est “numéroté” 0 (zéro).
var c:String = "0123456789";
var sousChaine=c.substr(1,3)
trace(sousChaine);
trace(c);// On est bien d'accord que la chaine d'origine n'est pas modifiée
123
0123456789

Notez que si le premier paramètre est négatif les caractères sont extraits depuis la fin de la chaine. Notez aussi que si le second paramètre est négatif (et le premier positif) l'index du dernier caractère est compté depuis la fin (utile pour récupérer une chaine moins son dernier caractère).

substring

Ne confondez pas substr et substring !

substring renvoie une sous-chaîne dont le premier caractère est précisé par le premier paramètre (comme substr) mais le deuxième paramètre précise l'index du dernier caractère moins 1 de la chaine extraite (et non la longueur).

var c:String = "0123456789";
var sousChaine=c.substring(1,3)
trace(sousChaine);
trace(c);// on est (toujours ;-)) bien d'accord que la chaine d'origine n'est pas modifiée
12
0123456789

Le plus pratique c'est encore de se livrer à des tests la fiche de synthèse est là pour ça.

indexOf

Comme son nom l'indique, cette méthode renvoie le numéro d'index de la chaine passée en premier argument, il peut bien sûr s'agir d'un ou plusieurs caractères.
Si la chaine n'est pas trouvée on récupère -1.

var c:String = "Du texte pour tester";
trace("o "+ c.indexOf("o"));
trace("e "+ c.indexOf("e"));// index de la première occurence rencontrée
trace("te "+ c.indexOf("te"));// index de la première occurence rencontrée
trace("tes "+ c.indexOf("tes"));
 
trace("z "+ c.indexOf("z"))
trace("d "+ c.indexOf("d"))
o 10
e 4
te 3
tes 14
z -1
d -1

• un deuxième argument facultatif (il vaut 0 par défaut) permet de préciser l'index de départ de la reherche (inclus)

trace("e depuis index 5 --> "+ c.indexOf("e",5));
e depuis index 5 --> 7

Un peu d'entrainement

En combinant habilement les bonnes méthodes on peut par exemple extraire le nom de domaine d'une adresse. Je vous renvoie une fois encore à la fiche de synthèse pour vous y entrainer.

L'événement CHANGE

On a vu au chapitre précédent que les objets d'affichage diffusaient des événements de type MouseEvent et qu'on pouvait écouter ces événements pour réagir aux actions de l'utilisateur.
Je disais en conclusion qu'une fois le principe diffusion/écoute/couplage compris, il en allait de même pour tous les autres types d'événements. C'est le moment de le vérifier ;)

La classe TextField diffuse un événement change de type Event à chaque fois que le contenu de l'instance est modifié (à chaque saisie, donc). Vérifions :

txtDemo.addEventListener(Event.CHANGE,qdSaisieTexte)
 
function qdSaisieTexte (e:Event):void {
	trace("je modifie le champ "+e.currentTarget+"  "+e.currentTarget.name);
}
je modifie le champ [object TextField]  txtDemo


:idea: N'oubliez pas le type dans le panneau de propriétés : saisie



Entrainement

Voilà qui peut vous permettre de forcer la frappe en majuscule.
Et voire encore plus fort : obliger une capitale pour le premier caractère et contraindre le reste à être en minuscules.

Vous voyez comment ?

Si vraiment vous séchez les (tous petits bouts de) code sont en bas du tuto.


Composants


Un mot vite fait de deux composants qui permettent eux aussi d'afficher et de gérer du texte : TextInput (une seule ligne) et TextAera (multiligne).

Ne confondez pas : ce ne sont pas des objets de la classe TextField, vous les trouverez dans le panneau latéral dans la catégorie (on dira paquetage) fl.controls. Leur principal intérêt réside dans le fait qu'ils distribuent non seulement un événement change mais aussi un événement enter de type ComponentEvent diffusé quand on appuie sur la touche entrée (à la validation, donc).


On en fait usage pour permettre à l'utilisateur de valider sa saisie au clavier (touche entrée) sans aller obligatoirement cliquer sur un bouton OK. Je n'en ai rien de plus à dire, s'il vous vient des questions n'hésitez pas à les poser dans le sujet dédié [lien bas de page].

Vous trouverez une synthèse de l'emploi des trois différents objets (TextField, TexttAera, TextInput) sur la deuxième page de la fiche ci-dessous.

Synthèse et Exos

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Cliquez sur les images réduites pour les développer.

Seules les deux premières pages nous concernent, et encore le moyen de modifier la couleur des champs texte fait-il appel à des choses que nous verrons plus tard, mais je préfère conserver tout ce qui “se mange ensemble” sur la même fiche ;)




Les "soluces" du comment forcer la frappe

Tout en majuscules :

txtDemo.addEventListener(Event.CHANGE,qdFrappe);
 
function qdFrappe (e:Event):void {
	e.currentTarget.text=e.currentTarget.text.toUpperCase()
}

Premier caractère en majuscule :

txtDemo.addEventListener(Event.CHANGE,qdFrappe);
 
function qdFrappe (e:Event):void {
	var premierCar:String=e.currentTarget.text.substr(0,1).toUpperCase();
	var laSuite:String=e.currentTarget.text.substr(1).toLowerCase();
	e.currentTarget.text=premierCar+laSuite
}
1) menu Contrôle/Tester l'animation [cmd-entrée]
2) et on l'affiche ;)
3) vérifiez si vous voulez