Класс FontMetrics
Класс FontMetrics является абстрактным, поэтому нельзя воспользоваться его конструктором. Для получения объекта класса FontMetrics, содержащего набор метрических характеристик шрифта f, надо обратиться к методу getFontMetrics (f) класса Graphics или класса Component.
Подробно с характеристиками компьютерных шрифтов можно познакомиться по книге.
Класс FontMetri.cs позволяет узнать ширину отдельного символа ch в пикселах методом charwidth(ch), общую ширину всех символов массива или под-массива символов или байтов методами getchars() и getBytes(), ширину целой строки str в пикселах методом stringwidth(str).
Несколько методов возвращают в пикселах вертикальные размеры шрифта.
Интерлиньяж (leading) — расстояние между нижней точкой свисающих элементов таких букв, как р, у и верхней точкой выступающих элементов таких букв, как б, и,
в
следующей строке — возвращает метод getLeading ().
Среднее расстояние от базовой линии шрифта до верхней точки прописных букв и выступающих элементов той же строки (ascent) возвращает метод getAscent (}, а максимальное — метод getMaxAscent ().
Среднее расстояние свисающих элементов от базовой линии той же строки (descent) возвращает метод getDescent (), а максимальное — метод
getMaxDescent().
Наконец, высоту шрифта (height) — сумму ascent + descent + leading — возвращает метод getHeight (). Высота шрифта равна расстоянию между базовыми линиями соседних строк.
Эти элементы показаны на рис. 9.1.
![](9.1.gif)
Рис. 9.1.
Элементы шрифта
Дополнительные характеристики шрифта можно определить методами класса LineMetrics из пакета java.awt.font. Объект этого класса можно получить несколькими методами getLineMetrics () класса FontMetrics.
Листинг 9.2 показывает применение графических примитивов и шрифтов, а рис. 9.2 — результат выполнения программы из этого листинга.
Листинг 9.2.
Использование графических примитивов и шрифтов
import java.awt.*;
import j ava.awt.event.*;
class GraphTest extends Frame{
GraphTest(String s) {
super(s);
setBounds(0, 0, 500, 300);
setVisible(true);
}
public void paint(Graphics g){
Dimension d = getSize();
int dx = d.width / 20, dy - d.height / 20;
g.drawRect(dx, dy + 20,
d.width - 2 * dx, d.height - 2 * dy - 20);
g.drawRoundRect(2 * dx, 2 * dy + 20,
d.width - 4 * dx, d.height -4 * dy - 20, dx, dy);
g.fillArctd.width / 2 - dx, d.height - 2 * dy + 1,
2 * dx, dy - 1, 0, 360);
g.drawArctd.width / 2 - 3 * dx, d.height - 3 * dy / 2 - 5,
dx, dy / 2, 0, 360);
g.drawArctd.width / 2 + 2 * dx, d.height - 3 * dy / 2 - 5,
dx, dy / 2, 0, 360);
Font fl = new Font("Serif", Font.BOLD(Font.ITALIC, 2 * dy);
Font f2 = new Font ("Serif", Font.BOLD, 5 * dy / 2);
FontMetrics fml = getFontMetrics(fl);
FontMetrics fm2 = getFontMetrics(f2);
String s1 = "Всякая последняя ошибка";
String s2 =« "является предпоследней.";
String s3 = "Закон отладки";
int firstLine = d.height / 3;
int nextLine = fml.getHeight();
int secondLine = firstLine + nextLine / 2;
g.setFont(f2);
g.drawstring(s3, (d.width-fm2.stringWidth(s3)) / 2, firstLine);
g.drawLine(d.width / 4, secondLine - 2,
3 * d.width / 4, secondLine - 2);
g.drawLine(d.width / 4, secondLine — 1,
3 * d.width / 4, secondLine - 1);
g.drawLine(d.width / 4, secondLine,
3 * d.width / 4, secondLine);
g.setFont(fl);
g.drawstring(s1, (d.width - fml.stringWidth(si))
12,
firstLine + 2 * nextLine);
g.drawString(s2, (d.width - fml.stringWidth(s2)) / 2,
firstLine + 3 * nextLine);
}
public static void main(String[] args){
GraphTest f = new GraphTest(" Пример рисования");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent ev){
System.exit(0);
}
});
}
}
В листинге 9. 2 использован простой класс Dimension, главная задача которого — хранить ширину и высоту прямоугольного объекта в своих полях width и height. Метод getsize () класса component возвращает размеры компонента в виде объекта класса Dimension. В листинге 9.2 размеры компонента f типа GrapMest установлены в конструкторе методом setBounds() равными 500x300 пикселов.
Еще одна особенность листинга 9.2 — для вычерчивания толстой линии, отделяющей заголовок от текста, пришлось провести три параллельные прямые на расстоянии один пиксел друг от друга.
Как вы увидели из обзора класса Graphics и сопутствующих ему классов, средства рисования и вывода текста в этом классе весьма ограничены. Линии можно проводить только сплошные и только толщиной в один пиксел, текст выводится только горизонтально и слева направо, не учитываются особенности устройства вывода, например, разрешение экрана.
Эти ограничения можно обойти разными хитростями: чертить несколько параллельных линий, прижатых друг к другу, как в листинге 9.2, или узкий заполненный прямоугольник, выводить текст по одной букве, получить разрешение экрана методом getScreenSize() класса Java.awt.Toolkit и использовать его в дальнейшем. Но все это затрудняет программирование, лишает его стройности и естественности, нарушает принцип KISS.
В Java 2 класс Graphics, в рамках системы Java 2D, значительно расширен классом Graphics2D.
![](9.2.gif)
Рис. 9.2.
Пример использования класса Graphics