Dessiner du texte est facile avec trois classes Java

En plus des méthodes de dessin de types géométriques primitifs tels que les lignes et les cercles, la Graphicsclasse fournit des méthodes pour dessiner du texte. Lorsqu'il est combiné avec les classes Fontet FontMetrics, le résultat est un ensemble d'outils qui rend le travail de dessin de texte attrayant beaucoup plus facile qu'il ne le serait autrement. Cette colonne couvrira tour à tour chacune de ces classes et vous montrera comment les utiliser ensemble. Avant de commencer, cependant, une brève revue du rôle de la Graphicsclasse s'impose.

Une critique

Afin d'utiliser les méthodes de texte de la Graphicsclasse, une compréhension du rôle de la Graphicsclasse elle-même est nécessaire. Cette section présente un bref aperçu de la fonction et du fonctionnement de la Graphicsclasse. Les lecteurs à la recherche d'une couverture complète devraient lire ma chronique d'octobre, disponible ici.

La Graphicsclasse joue deux rôles différents mais liés dans la boîte à outils de fenêtrage abstrait (AWT). Premièrement, il maintient le contexte graphique, qui comprend toutes les informations qui affecteront le résultat d'une opération graphique. Cela inclut la couleur du dessin, la police, l'emplacement et les dimensions du rectangle de détourage (la région dans laquelle les graphiques peuvent être dessinés). Plus important encore, le contexte graphique définit la destination des opérations graphiques sur le point d'être discutées (les destinations incluent des composants et des images).

Outre son rôle de contexte graphique, la Graphicsclasse fournit des méthodes pour dessiner des formes géométriques simples, du texte et des images vers la destination graphique. Toutes les opérations liées aux graphiques sur un composant ou une image se produisent via l'une de ces méthodes.

Pour dessiner, un programme nécessite un contexte graphique valide (représenté par une instance de la Graphicsclasse). Étant donné que la Graphicsclasse est une classe de base abstraite, elle ne peut pas être instanciée directement. Une instance est généralement créée par un composant, puis transmise au programme en tant qu'argument pour un composant update()et des paint()méthodes. Ces deux méthodes sont appelées dans le cadre du cycle de dessin normal lancé dans l'AWT.

La Graphicsclasse fonctionne avec les classes Fontet FontMetricspour fournir les outils nécessaires pour dessiner du texte dans une image ou un composant. Commençons par examiner les Graphicsméthodes de la classe pour dessiner du texte.

Graphiques de classe

La Graphicsclasse fournit trois méthodes qui dessinent du texte sur un composant ou une image.

void drawString (Chaîne str, int x, int y)

La drawString()méthode, illustrée ci-dessous, prend comme paramètres une instance de la Stringclasse contenant le texte à dessiner et deux valeurs entières spécifiant les coordonnées où le texte doit commencer.

public void paint (Graphiques g) {g.drawString ("abc", 25, 25); }

Le code dans la liste ci-dessus montre la drawString()méthode utilisée dans la paint()méthode d' un composant . Le code de cet exemple dessine le mot «abc» sur le composant contenant cette paint()méthode. Les coordonnées x et y spécifient l'emplacement du coin inférieur gauche de la zone de texte englobante. La figure 1 montre à quoi ressemblerait le résultat si ce code faisait partie d'un objet composant AWT approprié.

Figure 1: Une démonstration de drawString ()

void drawChars (char [] data, int offset, int length, int x, int y)

La drawChars()méthode ci-dessous prend comme paramètres un tableau de caractères contenant le texte à dessiner, une valeur entière indiquant le décalage dans le tableau à partir duquel commencer, une valeur entière indiquant le nombre de caractères à dessiner et deux valeurs entières spécifiant les coordonnées où le le texte doit commencer.

public void paint (Graphique g) {char [] rgc = {'a', 'b', 'c', 'd', 'e', ​​'f', 'g', 'h', 'i' 'j'};

g.drawChars (rgc, 0, 5, 25, 25); g.drawChars (rgc, 5, 5, 25, 50); }

Le code ci-dessus montre la drawChars()méthode utilisée dans la paint()méthode d' un composant . Le tableau de caractères est dessiné en deux parties. Dans le premier des deux appels à drawChars(), le paramètre offset indique que le dessin doit commencer par le premier caractère du tableau, et le paramètre length indique qu'un total de cinq caractères doit être dessiné sur la première ligne. Le deuxième des deux appels fonctionne de la même manière, mais dessine les cinq derniers caractères du tableau de caractères en commençant à une position 25 pixels sous le premier. La figure 2 montre à quoi ressemblerait le résultat si ce code faisait partie d'un objet composant AWT approprié.

Figure 2: Une démonstration drawChars ()

void drawBytes (byte [] data, décalage int, longueur int, int x, int y)

Comme indiqué ci-dessous, la drawBytes()méthode prend comme paramètres un tableau d'octets contenant le texte à dessiner, une valeur entière indiquant le décalage dans le tableau auquel commencer, une valeur entière indiquant le nombre d'octets à dessiner et deux valeurs entières spécifiant le coordonnées où le texte doit commencer.

public void paint (Graphiques g) {byte [] rgb = {'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'};

g.drawBytes (rgb, 0, 5, 25, 25); g.drawBytes (rgb, 5, 5, 25, 50); }

Le code ci-dessus montre la drawBytes()méthode utilisée dans la paint()méthode d' un composant . La figure 3 montre à quoi ressemblerait le résultat si ce code faisait partie d'un objet composant AWT approprié.

Figure 3: Une démonstration drawBytes ()

Prise en charge Unicode

L'une des fonctionnalités les plus vantées de Java est sa prise en charge des scripts internationaux via Unicode. Il est regrettable que la bibliothèque de classes Java fournie avec la version 1.0 du langage de programmation Java n'ait pas entièrement pris en charge cette facette du langage. Cependant, il semble que de bonnes nouvelles soient imminentes. L'API d'internationalisation préliminaire (voir Ressources), disponible auprès de SunSoft, a ceci à dire:

JDK 1.0 était limité à afficher uniquement les caractères du sous-ensemble Latin-1 d'Unicode. Cette restriction est supprimée dans JDK 1.1. Les programmes Java pourront désormais afficher n'importe quel caractère Unicode qui peut être rendu avec une police hôte. Java fournit un petit nombre de noms de polices "virtuels" prédéfinis et les mappe aux polices réelles disponibles sur l'hôte. Dans JDK 1.0, chaque nom de police Java correspond à exactement une police hôte. Dans JDK 1.1, un nom de police Java peut être mappé à une série de polices hôtes. La série de polices hôtes peut être choisie pour couvrir autant de jeu de caractères Unicode que souhaité.

Placement du texte

Parce que le texte n'est qu'un autre type de figure pour l'AWT, une ligne de texte peut être placée n'importe où, même au-dessus d'une autre ligne de texte. L'effet d'un placement au hasard, cependant, ne sera pas nécessairement agréable à l'œil. Afin d'aider le programmeur à produire un texte esthétique, une définition de police comprend des directives pour le placement des lignes et des caractères. Ces directives, si elles sont suivies, aideront à produire un résultat agréable.

La figure 4 contient une ligne de texte qui a été balisée pour indiquer les caractéristiques dont nous sommes sur le point de discuter.

Figure 4: Une ligne de texte

Le paramètre de coordonnée y dans les méthodes de la section précédente spécifie l'emplacement de la ligne de base d'une ligne de texte. La ligne de base est la ligne sur laquelle reposent la plupart des caractères d'une ligne de texte (l'exception étant les caractères avec des descendants tels que "g" et "y"). La ligne de base n'est pas vraiment une caractéristique d'une police, mais est le point de référence auquel toutes les autres caractéristiques se réfèrent.

L' ascension est la distance entre la ligne de base et le haut de la plupart des caractères d'une police. Il s'agit généralement de la hauteur des majuscules dans la police et des caractères tels que "f" et "h". Ce chiffre n'est cependant qu'une indication. Certains caractères de la police peuvent en fait dépasser cette distance.

La descente est la distance entre la ligne de base et le bas des caractères dans une police qui ont des descendants - des caractères comme "p", "g" et "y". Comme pour l'ascension, ce chiffre n'est qu'une indication. Certains caractères de la police peuvent en fait dépasser cette distance.

Le premier (prononcé « Ledding ») est la quantité d'espace entre la descente d'une ligne de texte et la montée de la ligne en dessous. La hauteur d'une ligne de texte (la distance entre la ligne de base d'une ligne de texte et la ligne de base d'une ligne de texte au-dessus ou en dessous) comprend cet espace supplémentaire.

En plus des caractéristiques régissant une police dans son ensemble, chaque caractère d'une police a une avance . L'avance spécifie le nombre de pixels séparant le début du caractère du début d'un caractère à sa droite; bref, c'est la largeur d'un personnage. Encore une fois, certains caractères d'une police peuvent en fait dépasser cette distance.

En additionnant les largeurs de tous les caractères d'une ligne de texte, la longueur de la ligne entière de texte peut être calculée. La FontMetricsclasse ci-dessous fournit une méthode qui fait exactement cela, et plus encore.

Classe FontMetrics

La FontMetricsclasse fournit un moyen simple d'obtenir les caractéristiques décrites ci-dessus. Voici la getFontMetricsméthode en action:

public void paint (Graphiques g) {FontMetrics fm = g.getFontMetrics (); . . . }

Le code ci-dessus montre comment obtenir les informations de métrique de police décrivant la police actuelle. La getFontMetrics()méthode renvoie une instance de la FontMetricsclasse. La FontMetricsclasse fournit les méthodes suivantes:

int getAscent()

  • Renvoie l'ascension de la police.

int getDescent()

  • Renvoie la descente de la police.

int getLeading()

  • Renvoie le début de la police.

int getHeight()

  • Renvoie la hauteur de la police. La hauteur est la somme de la montée, de la descente et de la direction de la police.

int charWidth(int ch)

  • Renvoie la largeur du caractère spécifié.

int charWidth(char ch)

  • Renvoie la largeur du caractère spécifié.

int [] getWidths()

  • Renvoie un tableau d'entiers contenant les largeurs des 256 premiers caractères de la police.

Comme mentionné ci-dessus, les caractères qui composent une police peuvent parfois s'étendre au-delà de la montée, de la descente et des largeurs signalées par les méthodes ci-dessus. Dans les cas où des valeurs exactes sont requises, les méthodes suivantes sont fournies.

int getMaxAscent()

  • Renvoie l'ascension maximale de la police.

int getMaxDescent()

  • Renvoie la descente maximale de la police.

int getMaxAdvance()

  • Renvoie la largeur du caractère le plus large de la police.

Les méthodes suivantes fournissent des informations sur la largeur occupée par une séquence de caractères.

int stringWidth(String str)

  • Renvoie la largeur de la séquence de caractères.

int bytesWidth(byte [] rgb, int offset, int length)

  • Renvoie la largeur de la longueur longue séquence d'octets à partir de décalage .

int charsWidth(char [] rgc, int offset, int length)

  • Renvoie la largeur de la longueur longue séquence de caractères commençant à décalage .

Police de classe

La Fontclasse encapsule des informations sur une police. Une nouvelle police est produite en créant une instance de la Fontclasse avec un nom, un style et une taille en points.

Police f = nouvelle police ("Dialog", Font.PLAIN, 12); 

Une fois créée, une police peut être affectée à une instance de l' Graphicsobjet.

g.setFont (f); 

L' Graphicsobjet utilisera alors la police pour toutes les opérations graphiques ultérieures liées au texte.

La Fontclasse fournit des méthodes pour obtenir des informations sur une police une fois qu'elle a été créée.

String getName()

  • Renvoie le nom de la police.

String getFamily()

  • Renvoie le nom spécifique à la plate-forme de la police.

int getSize()

  • Renvoie la taille en points de la police.

int getStyle()

  • Renvoie le style de la police.

boolean isBold()

  • Renvoie truesi la police est en gras.

boolean isItalic()

  • Renvoie truesi la police est en italique.

boolean isPlain()

  • Renvoie truesi la police est simple.

String getName()

  • Renvoie le nom de la police.

Une démonstration

L'applet de la figure 5 affiche une ligne de texte avec un balisage suffisant pour indiquer les valeurs des métriques associées de la section ci-dessus. Une ligne noire épaisse se trouve à la ligne de base. Deux lignes supplémentaires indiquent la montée et la descente de la police en question. Des lignes verticales plus petites indiquent la largeur des caractères. Les trois menus déroulants vous permettent de sélectionner une police, son style et sa taille en points.

Vous avez besoin d'un navigateur compatible Java pour afficher cette applet. Figure 5: Un navigateur de métrique de police interactif

L'applet utilise les Graphics, Fontet les FontMetricsclasses largement. Sa source est disponible ici.

Conclusion

Il semble que la Graphicsclasse s'est avérée être un terrain très fertile pour l'exploration. Et l'expédition n'est pas encore terminée. Le mois prochain, je terminerai mon excursion dans la Graphicsclasse avec une colonne sur ses méthodes de support d'image, et cette colonne commencera une petite série sur d'autres sujets liés aux images et à l'AWT, y compris les producteurs d'images et les consommateurs d'images.

Je tiens à remercier tous ceux qui ont pris le temps de m'écrire avec vos commentaires, idées et suggestions. Continuez votre bon travail.

Todd Sundsted a écrit des programmes depuis que les ordinateurs sont devenus disponibles dans les modèles de bureau. Bien qu'à l'origine intéressé par la création d'applications d'objets distribués en C ++, Todd est passé au langage de programmation Java lorsque Java est devenu le choix évident pour ce genre de choses. Todd est co-auteur de l'API Java Language SuperBible, maintenant dans les librairies partout. En plus de l'écriture, Todd fournit des services de consultation Internet et Web aux entreprises du sud-est des États-Unis.

En savoir plus sur ce sujet

  • L' GraphicsAPI de classe :

    //www.javasoft.com/products/JDK/CurrentRelease/api/java.awt.Graphics.html

  • L' FontAPI de classe :

    //www.javasoft.com/products/JDK/CurrentRelease/api/java.awt.Graphics.html

  • L' FontMetricsAPI de classe :

    //www.javasoft.com/products/JDK/CurrentRelease/api/java.awt.Graphics.html

  • Utilisation de la Graphicsclasse:

    //www.javaworld.com/javaworld/jw-11-1996/jw-11-howto.html

  • L'API d'internationalisation:

    //www.javasoft.com/products/JDK/1.1/docs/guide/intl/index.html

  • Le tutoriel Java par Mary Campione et Kathy Walrath:

    //www.javasoft.com/books/Series/Tutorial/index.html

Cette histoire, "Dessiner du texte est facile avec trois classes Java" a été initialement publiée par JavaWorld.