Dibujar texto es fácil con tres clases de Java

Además de los métodos para dibujar tipos geométricos primitivos como líneas y círculos, la Graphicsclase proporciona métodos para dibujar texto. Cuando se combina con las clases Fonty FontMetrics, el resultado es un conjunto de herramientas que hace que el trabajo de dibujar texto atractivo sea mucho más fácil de lo que sería de otra manera. Esta columna cubrirá cada una de estas clases por turno y le mostrará cómo usarlas juntas. Sin embargo, antes de comenzar, conviene hacer un breve repaso del papel de la Graphicsclase.

Una revisión

Para utilizar los métodos de texto de la Graphicsclase, Graphicsse requiere una comprensión del papel de la clase en sí. Esta sección presenta una breve descripción de la función y el funcionamiento de la Graphicsclase. Los lectores que busquen una cobertura completa deben leer mi columna de octubre, disponible aquí.

La Graphicsclase juega dos roles diferentes pero relacionados dentro del conjunto de herramientas de ventanas abstractas (AWT). Primero, mantiene el contexto gráfico, que consiste en toda la información que afectará el resultado de una operación gráfica. Esto incluye el color del dibujo, la fuente y la ubicación y las dimensiones del rectángulo de recorte (la región en la que se pueden dibujar los gráficos). Más importante aún, el contexto gráfico define el destino de las operaciones gráficas que se van a discutir (los destinos incluyen componentes e imágenes).

Además de su función como contexto gráfico, la Graphicsclase proporciona métodos para dibujar formas geométricas simples, texto e imágenes en el destino de los gráficos. Todas las operaciones relacionadas con los gráficos en un componente o imagen se producen mediante uno de estos métodos.

Para dibujar, un programa requiere un contexto gráfico válido (representado por una instancia de la Graphicsclase). Debido a que la Graphicsclase es una clase base abstracta, no se puede instanciar directamente. Por lo general, un componente crea una instancia y luego la entrega al programa como argumento para los métodos update()y de un componente paint(). Estos dos métodos se llaman como parte del ciclo de dibujo normal iniciado dentro del AWT.

La Graphicsclase trabaja junto con las clases Fonty FontMetricspara proporcionar las herramientas necesarias para dibujar texto dentro de una imagen o componente. Comencemos examinando los Graphicsmétodos de la clase para dibujar texto.

Gráficos de clase

La Graphicsclase proporciona tres métodos que dibujan texto en un componente o una imagen.

void drawString (String str, int x, int y)

El drawString()método, que se muestra a continuación, toma como parámetros una instancia de la Stringclase que contiene el texto que se va a dibujar y dos valores enteros que especifican las coordenadas donde debe comenzar el texto.

pintura vacía pública (Gráficos g) {g.drawString ("abc", 25, 25); }

El código de la lista anterior muestra el drawString()método en uso dentro del paint()método de un componente . El código de este ejemplo dibuja la palabra "abc" en el componente que contiene este paint()método. El X e Y las coordenadas especifican la ubicación de la inferior izquierda esquina de la caja de texto que encierra. La Figura 1 muestra cómo se vería el resultado si este código fuera parte de un objeto de componente AWT adecuado.

Figura 1: demostración de drawString ()

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

El drawChars()siguiente método toma como parámetros una matriz de caracteres que contiene el texto que se dibujará, un valor entero que indica el desplazamiento en la matriz en la que comenzar, un valor entero que indica el número de caracteres a dibujar y dos valores enteros que especifican las coordenadas el texto debe comenzar.

pintura vacía pública (Gráficos 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); }

El código anterior muestra el drawChars()método en uso dentro del paint()método de un componente . La matriz de caracteres se dibuja en dos partes. En la primera de las dos llamadas a drawChars(), el parámetro de desplazamiento indica que el dibujo debe comenzar con el primer carácter de la matriz y el parámetro de longitud indica que se debe dibujar un total de cinco caracteres en la primera línea. La segunda de las dos llamadas funciona de manera similar, pero dibuja los últimos cinco caracteres en la matriz de caracteres comenzando en una posición 25 píxeles por debajo de la primera. La Figura 2 muestra cómo se vería el resultado si este código fuera parte de un objeto de componente AWT adecuado.

Figura 2: Una demostración de drawChars ()

vacío drawBytes (byte [] datos, int desplazamiento, int longitud, int x, int y)

Como se muestra a continuación, el drawBytes()método toma como parámetros una matriz de bytes que contiene el texto que se va a dibujar, un valor entero que indica el desplazamiento en la matriz en la que comenzar, un valor entero que indica el número de bytes a dibujar y dos valores enteros que especifican el coordenadas donde debe comenzar el texto.

pintura vacía pública (Gráficos 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); }

El código anterior muestra el drawBytes()método en uso dentro del paint()método de un componente . La Figura 3 muestra cómo se vería el resultado si este código fuera parte de un objeto de componente AWT adecuado.

Figura 3: Una demostración de drawBytes ()

Soporte Unicode

Una de las características más promocionadas de Java es su soporte para scripts internacionales a través de Unicode. Es una lástima que la biblioteca de clases Java suministrada con la versión 1.0 del lenguaje de programación Java no sea totalmente compatible con esta faceta del lenguaje. Sin embargo, parece que las buenas noticias están a la vuelta de la esquina. La API de internacionalización preliminar (ver Recursos), disponible en SunSoft, tiene esto que decir:

JDK 1.0 se limitó a mostrar solo los caracteres en el subconjunto Latin-1 de Unicode. Esta restricción se elimina en JDK 1.1. Los programas Java ahora podrán mostrar cualquier carácter Unicode que se pueda representar con una fuente de host. Java proporciona una pequeña cantidad de nombres de fuentes "virtuales" predefinidos y los asigna a fuentes reales disponibles en el host. En JDK 1.0, cada nombre de fuente Java se asigna exactamente a una fuente de host. En JDK 1.1, un nombre de fuente Java se puede asignar a una serie de fuentes de host. La serie de fuentes de host se puede elegir para cubrir la mayor cantidad de caracteres Unicode que se desee.

Colocación de texto

Debido a que el texto es solo otro tipo de figura para el AWT, una línea de texto se puede colocar en cualquier lugar, incluso encima de otra línea de texto. Sin embargo, el efecto de la colocación aleatoria no será necesariamente agradable a la vista. Para ayudar al programador a producir texto estéticamente agradable, una definición de fuente incluye pautas para la colocación de líneas y caracteres. Estas pautas, si se siguen, ayudarán a producir resultados satisfactorios.

La Figura 4 contiene una línea de texto que se ha marcado para indicar las características que estamos a punto de discutir.

Figura 4: Una línea de texto

El parámetro de coordenada y en los métodos de la sección anterior especifica la ubicación de la línea de base de una línea de texto. La línea de base es la línea sobre la que descansan la mayoría de los caracteres de una línea de texto (con la excepción de los caracteres con descendentes como "g" e "y"). La línea de base no es realmente una característica de una fuente, pero es el punto de referencia al que se refieren todas las demás características.

El ascenso es la distancia desde la línea de base hasta la parte superior de la mayoría de los caracteres de una fuente. Esta suele ser la altura de las letras mayúsculas de la fuente y de caracteres como "f" y "h". Sin embargo, esta cifra es solo una guía. Algunos caracteres de la fuente pueden extenderse por encima de esta distancia.

El descenso es la distancia desde la línea de base hasta la parte inferior de los caracteres en una fuente que tiene descendientes: caracteres como "p", "g" e "y". Al igual que con el ascenso, esta cifra es solo una guía. Algunos caracteres de la fuente pueden extenderse por debajo de esta distancia.

El interlineado (pronunciado "ledding") es la cantidad de espacio entre el descenso de una línea de texto y el ascenso de la línea inferior. La altura de una línea de texto (la distancia desde la línea de base de una línea de texto a la línea de base de una línea de texto por encima o por debajo) incluye este espacio adicional.

Además de las características que rigen una fuente en su conjunto, cada carácter de una fuente tiene un avance . El avance especifica cuántos píxeles separan el comienzo del carácter del comienzo de un carácter a su derecha; en resumen, es el ancho de un carácter. Una vez más, algunos caracteres de una fuente pueden extenderse más allá de esta distancia.

Al sumar los anchos de todos los caracteres en una línea de texto, se puede calcular la longitud de toda la línea de texto. La FontMetricssiguiente clase proporciona un método que hace precisamente esto y más.

Clase FontMetrics

La FontMetricsclase proporciona una forma sencilla de llegar a las características discutidas anteriormente. Aquí está el getFontMetricsmétodo en acción:

pintura vacía pública (Gráficos g) {FontMetrics fm = g.getFontMetrics (); . . . }

El código anterior demuestra cómo se puede obtener la información de métricas de fuente que describe la fuente actual. El getFontMetrics()método devuelve una instancia de la FontMetricsclase. La FontMetricsclase proporciona los siguientes métodos:

int getAscent()

  • Devuelve el ascenso de la fuente.

int getDescent()

  • Devuelve el descenso de la fuente.

int getLeading()

  • Devuelve el principio de la fuente.

int getHeight()

  • Devuelve la altura de la fuente. La altura es la suma del ascenso, descenso y avance de la fuente.

int charWidth(int ch)

  • Devuelve el ancho del carácter especificado.

int charWidth(char ch)

  • Devuelve el ancho del carácter especificado.

int [] getWidths()

  • Devuelve una matriz de enteros que contiene los anchos de los primeros 256 caracteres de la fuente.

Como se mencionó anteriormente, los caracteres que componen una fuente a veces pueden extenderse más allá del ascenso, descenso y anchos informados por los métodos anteriores. En los casos en que se requieran valores exactos, se proporcionan los siguientes métodos.

int getMaxAscent()

  • Devuelve el ascenso máximo de la fuente.

int getMaxDescent()

  • Devuelve el descenso máximo de la fuente.

int getMaxAdvance()

  • Devuelve el ancho del carácter más ancho de la fuente.

Los siguientes métodos proporcionan información sobre el ancho que ocupa una secuencia de caracteres.

int stringWidth(String str)

  • Devuelve el ancho de la secuencia de caracteres.

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

  • Devuelve la anchura de la longitud larga secuencia de bytes a partir de las de desplazamiento .

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

  • Devuelve el ancho de la longitud larga secuencia de caracteres que comienza en compensado .

Fuente de clase

La Fontclase encapsula información sobre una fuente. Se produce una nueva fuente creando una instancia de la Fontclase con un nombre, estilo y tamaño en puntos.

Font f = new Font ("Diálogo", Font.PLAIN, 12); 

Una vez creada, se puede asignar una fuente a una instancia del Graphicsobjeto.

g.setFont (f); 

El Graphicsobjeto utilizará la fuente para todas las operaciones de gráficos relacionadas con el texto posteriores.

La Fontclase proporciona métodos para obtener información sobre una fuente una vez que se ha creado.

String getName()

  • Devuelve el nombre de la fuente.

String getFamily()

  • Devuelve el nombre específico de la plataforma de la fuente.

int getSize()

  • Devuelve el tamaño en puntos de la fuente.

int getStyle()

  • Devuelve el estilo de la fuente.

boolean isBold()

  • Devuelve truesi la fuente está en negrita.

boolean isItalic()

  • Devuelve truesi la fuente está en cursiva.

boolean isPlain()

  • Devuelve truesi la fuente es simple.

String getName()

  • Devuelve el nombre de la fuente.

Una demostración

El subprograma de la Figura 5 muestra una línea de texto con suficiente marcado para indicar los valores de las métricas asociadas de la sección anterior. Una línea negra gruesa se encuentra en la línea de base. Dos líneas adicionales indican el ascenso y descenso de la fuente en cuestión. Las líneas verticales más pequeñas indican el ancho de los caracteres. Los tres menús desplegables le permiten seleccionar una fuente, su estilo y su tamaño en puntos.

Necesita un navegador compatible con Java para ver este subprograma. Figura 5: Un navegador de métricas de fuentes interactivas

El applet utiliza los Graphics, Fonty FontMetricslas clases ampliamente. Su fuente está disponible aquí.

Conclusión

Parece que la Graphicsclase ha resultado ser un terreno muy fértil para la exploración. Y la expedición aún no ha terminado. El próximo mes terminaré mi excursión a la Graphicsclase con una columna sobre sus métodos de soporte de imágenes, y esa columna comenzará una pequeña serie sobre otros temas relacionados con las imágenes y el AWT, incluidos los productores de imágenes y los consumidores de imágenes.

Me gustaría agradecerles a todos los que se han tomado el tiempo de escribirme con sus comentarios, ideas y sugerencias. Sigan con el buen trabajo.

Todd Sundsted ha estado escribiendo programas desde que las computadoras estuvieron disponibles en modelos de escritorio. Aunque originalmente estaba interesado en construir aplicaciones de objetos distribuidos en C ++, Todd se mudó al lenguaje de programación Java cuando Java se convirtió en la opción obvia para ese tipo de cosas. Todd es coautor de Java Language API SuperBible, ahora en las librerías de todo el mundo. Además de escribir, Todd ofrece servicios de consultoría de Internet y Web a empresas del sureste de los Estados Unidos.

Más información sobre este tema

  • La clase GraphicsAPI:

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

  • La clase FontAPI:

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

  • La clase FontMetricsAPI:

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

  • Usando la Graphicsclase:

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

  • La API de internacionalización:

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

  • El tutorial de Java de Mary Campione y Kathy Walrath:

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

Esta historia, "Dibujar texto es fácil con tres clases de Java" fue publicada originalmente por JavaWorld.